Adding to an array in an external file, and adding elements to it.


 
Thread Tools Search this Thread
Top Forums UNIX for Beginners Questions & Answers Adding to an array in an external file, and adding elements to it.
# 15  
Old 03-19-2019
OK, having taken a better look at what you're doing, I think this is what you were looking for. It loads from a newline-separated file, and can append to it. main() returns a value depending on what option you select, 1 for the first line, etc, etc, or 127 if no selection.

Code:
#include <ncurses.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>      // for isspace()

int barmenu(const char const **array, int row, int col,
        int arraylength, int width, int menulength, int selection);

// Removes whitespace from the end of strings
void chomp(char *str)
{
        int len=strlen(str);

        if(len>0)
        while((len>0) && isspace(str[len-1]))
                str[--len]='\0';
}

int main(void)
{
        char buf[128];
        int selection,row=1,col=10,arraylength=0,width=5, menulength=5;

        char **testarray=NULL;
        FILE *fp=fopen("filename","r");

        while(fgets(buf,128,fp) != NULL)
        {
                chomp(buf); // Remove \n from end of line
                if(strlen(buf) > width) width=strlen(buf);
                if(!buf[0]) continue; // Ignore blank lines

                arraylength++;
                // Room for n+1 elements of char * size.
                testarray=realloc(testarray, sizeof(char *)*(arraylength+1));
                // strdup is an easy str=malloc(strlen(s)+1); strcpy(str,s);
                testarray[arraylength-1]=strdup(buf);
        }

        // The +1 gives us room for a NULL on the end.  Makes it easier to find crashes.
        testarray[arraylength]=NULL;
        fclose(fp);

        // If no elements were loaded, it will still be NULL
        if(testarray == NULL)
        {
                fprintf(stderr, "Unable to load options\n");
                exit(1);
        }

        initscr();
        noecho();
        keypad(stdscr,TRUE);

        selection=barmenu((const char const **)testarray,row,col,arraylength,width,menulength,0);

        mvprintw(15,0,"Selection= %d",selection);
        refresh();
        getch();
        endwin();

        // Add another option to file
        fp=fopen("filename","a");
        fputs("whatever\n", fp);
        fclose(fp);

        // We allocated all this stuff, so free it.
        for(col=0; col<arraylength; col++) if(testarray[col]) free(testarray[col]);
        free(testarray);

        // Cannot return -1 to commandline.  127 is the maximum we should return.
        if(selection < 0) return(127);
        // 0 has special meaning, return n+1
        return selection+1;
}

int barmenu(const char const **array, int row, int col,
        int arraylength, int width, int menulength, int selection)
{
        int counter,offset=0,ky=0;
         char formatstring[7];
         curs_set(0);

         if (arraylength < menulength)
                 menulength=arraylength;

         if (selection > menulength)
                 offset=selection-menulength+1;

         sprintf(formatstring,"%%-%ds",width); // remove - sign to right-justify the menu items

         while(ky != 27)
                 {
                 for (counter=0; counter < menulength; counter++)
                         {
                         if (counter+offset==selection)
                                 attron(A_REVERSE);
                         mvprintw(row+counter,col,formatstring,array[counter+offset]);
                         attroff(A_REVERSE);
                         }

                 ky=getch();

                 switch(ky)
                         {
                         case KEY_UP:
                                 if (selection)
                                         {
                                         selection--;
                                         if (selection < offset)
                                                 offset--;
                                         }
                                 break;
                         case KEY_DOWN:
                                 if (selection < arraylength-1)
                                         {
                                         selection++;
                                         if (selection > offset+menulength-1)
                                                 offset++;
                                         }
                                 break;
                         case KEY_HOME:
                                 selection=0;
                                 offset=0;
                                 break;
                         case KEY_END:
                                 selection=arraylength-1;
                                 offset=arraylength-menulength;
                                 break;
                         case KEY_PPAGE:
                                 selection-=menulength;
                                 if (selection < 0)
                                         selection=0;
                                 offset-=menulength;
                                 if (offset < 0)
                                         offset=0;
                                 break;
                         case KEY_NPAGE:
                                 selection+=menulength;
                                 if (selection > arraylength-1)
                                         selection=arraylength-1;
                                 offset+=menulength;
                                 if (offset > arraylength-menulength)
                                         offset=arraylength-menulength;
                                 break;

                         case 10: //enter
                                 return selection;
                                 break;
                         case KEY_F(1): // function key 1
                                 return -1;
                         case 27: //esc
                                 // esc twice to get out, otherwise eat the chars that don't work
                                 //from home or end on the keypad
                                 ky=getch();
                                 if (ky == 27)
                                         {
                                         curs_set(0);
                                         mvaddstr(9,77,"   ");
                                         return -1;
                                         }
                                 else
                                         if (ky=='[')
                                                 {
                                                 getch();
                                                 getch();
                                                 }
                                         else
                                                 ungetch(ky);
                         }
                 }
         return -1;
}


Last edited by Corona688; 03-19-2019 at 01:16 PM..
# 16  
Old 03-19-2019
Ok. Sorry for not being able to post my code here. Here's some more code.



int conn() { char c[1000]; FILE *fptr; if ((fptr = fopen(" - Pastebin.com


My question is simple: how do I select which data is read by fscanf?


Code:
fscanf(fptr,"%[^\n]", c);

Reads until a newline is detected. I'd like to be able to read a certain line in the text file (contact.txt).
Possibly with user input. Is this possible?
# 17  
Old 03-19-2019
Thank you for the code. It doesn't do exactly what I want it to do, but it helps. Thanks.
# 18  
Old 03-20-2019
Quote:
My question is simple: how do I select which data is read by fscanf?
My answer is simple: However you want.

More specifically, scanf cannot seek line 5. (neither can fseek -- they count bytes, not lines.) To get to line 5, read 4 lines:

Code:
int line=5;
char buf[512];
FILE *fp=fopen("file.txt", "r");
while(--line) fgets(buf, 512, fp);
// You are now at line 5.
code_to_read_fifth_line();

Next, rule #1 of C is "never, ever, ever use fscanf". If you absolutely must use scanf, use sscanf. read one line at a time with fgets like I showed you, clean them up with chomp like I showed you, then call sscanf(string, "whatever", arguments);. That will avoid most of scanf's inevitable stumbling blocks.

First problem, scanf has a buffering issue, which is probably why it's not doing what you expect. The first time you call it, it will read until a newline is detected. The second time you call it, it reads until the exact same newline is detected! That newline was never matched, so is still there.

However, fscanf has another problem. What if one of those lines is 1000 bytes but your buffer is only 10? Crash!

You can fix the first issue, to a point. You have to tell fscanf everything it should expect, including the stuff you don't want to keep. Only % codes get read into variables, other stuff gets silently skipped. fscanf(fp, "%[^\r\n]\r\n", c); But if you ever end up with input you didn't specify, fscanf will quite literally choke on it. That's why I specify \r\n here instead of \n. That was a crash issue in software I ported from Windows to UNIX - fscanf had to be amended to accommodate Windows-style carriage returns. \r\n works with both here.

A better example of the way scanf thinks might be sscanf("abcde12345fghijk", "abcde%dfghijk", &number); abcde and fghijk get matched without being stored, only %d is stored because of the %. If you fed it the string "abcdf12345fghijk" it would read "abcd" and stop at f, where it stops agreeing with the string you gave it. The & is required for atomic types - integers and floating point. Strings don't get the & because character arrays are already pointers as far as C's concerned.

Quote:
Thank you for the code. It doesn't do exactly what I want it to do, but it helps. Thanks.
Then what do you want? Your questions are both too specific and not specific enough because you're making hasty choices looking for solutions to problems we don't know about. Like the "inserting text into header file" question as a workaround to actually loading a normal text file. Please explain and I might be able to do what you want. How is telnet involved here? What are you actually doing?

Last edited by Corona688; 03-20-2019 at 01:36 PM..
# 19  
Old 03-20-2019
I'm writing a telnet BBS client. The code i've showed you is the user interface code. I have a telnet function, which, obviously, telnets to a certain address, specified by which line the arrow key selects in the array. My problems are:


1) I have to recompile, every time a BBS is added to the array. Which is an external file.

2) The array is limited to twenty (20) BBSes.. or elements, however you want to look at it


I hope this illustrates what i'm trying to do. And hopefully you understand what i'm trying to do.
Any specific questions?.
# 20  
Old 03-20-2019
You know how to load from file now. Why not load the BBSes from file too? They could be the same file even.
# 21  
Old 03-20-2019
Excuse my ignorance, but how would I do that?


Code:
FILE *fp=fopen("file.txt", "r");

Is what i'm thinking.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Adding Two Array in shell script

Hi Experts, I've got this problem where I need to add two array in shell script such that that is an element is greater than 9 then it get further split into individual digit, something like below : Input :- array1=(2 6 8 9 10 12) array2=(5 4 6 8 12 14) Output :- array3=(7 1 0 1 4 1 7 2 2... (8 Replies)
Discussion started by: mukulverma2408
8 Replies

2. Solaris

Solaris - Sendmail - Adding .com.gr in external senders e-mails

Hello Everybody ! I'm Harry from Athens Greece and i have a problem with my Sendmail 8.13.3 installed on Solaris SunOS ultra 5.10. The problem is that when someone sends to us an e-mail and his e-mail address is like : xxxx@xxxx.com, our e-mail server adds up in the senders address a .com.gr... (2 Replies)
Discussion started by: Mcasim
2 Replies

3. Shell Programming and Scripting

Adding an element to a bash array with a variable

Hello, I have a simple task and I am having some trouble with the syntax. I have a variable with an assigned value, CMD_STRING='-L 22 -s 0 -r -O -A i -N 100 -n' I would like to add that variable to an array. As far as I have been able to look up, the syntax should be something like, ... (4 Replies)
Discussion started by: LMHmedchem
4 Replies

4. Shell Programming and Scripting

Adding results of a find to an array

I'm trying to add the paths of all the xml files in certain directories to an array. I want to use the array later in my code. Anyway, for some reason this isn't working. Any help would be appreciated. Path_Counter=0 for result in "find * -name '*.xml'"; do XmlPath="$result" echo... (2 Replies)
Discussion started by: Fly_Moe
2 Replies

5. Shell Programming and Scripting

Adding new lines to a file + adding suffix to a pattern

I need some help with adding lines to file and substitute a pattern. Ok I have a file: #cat names.txt name: John Doe stationed: 1 name: Michael Sweets stationed: 41 . . . And would like to change it to: name: John Doe employed permanently stationed: 1-office (7 Replies)
Discussion started by: hemo21
7 Replies

6. Shell Programming and Scripting

Problem adding into an array field!!!

Hi, Kindly assist by analyzing the code below and suggest changes to achieve the required output. The input file: 01-010241800000 35000 MV010 02/03/09 0306 03060226 03 02-004103300000 470000 MV010 02/03/09 0301 03010276 03 The objective is to convert field No4. from dd/mm/yy to yyyymmdd... (5 Replies)
Discussion started by: talk2pawee
5 Replies

7. Solaris

Adding external disk array to a live server

Hi all Ive got a v440 with an external T3 RAID in a dual bus configuration. I need to add an additional JBOD extension to the disk array via two VDCH cables. Now, can I do this as the server is live ? Can I just plug the two cables in, switch on the additional extension ? Will this cause... (1 Reply)
Discussion started by: sbk1972
1 Replies

8. Shell Programming and Scripting

Adding array element in KSH

All, I would like to add the first 10 elements of an array. Here is how I am doing it now (only included first few add ops): #!/usr/bin/ksh ###Grab the array values out of a file### TOTAL=`awk '/time/' /tmp/file.out | awk '{print $4}'` set -A times $TOTAL SUM=$((${times} + times... (3 Replies)
Discussion started by: Shoeless_Mike
3 Replies

9. Shell Programming and Scripting

Search array elements as file for a matching string

I would like to find a list of files in a directory less than 2 days old and put them into an array variable. And then search for each file in the array for a matching string say "Return-code= 0". If it matches, then display the array element with a message as "OK". Your help will be greatly... (1 Reply)
Discussion started by: mkbaral
1 Replies

10. Solaris

adding existing disks to a 3510 array

I would like to extend a logical drive on our 3510. I have four unallocated disks which I would like to use for this purpose. The 3510 supports a Sun Cluster but for now all I wish to see is a "new" disk when I run format. I am a little familiar with the telnet/ssh session on the 3510 but am... (2 Replies)
Discussion started by: malcqv
2 Replies
Login or Register to Ask a Question