Search code examples
carrayspointerscharsystem

Storing line by line from text file into char array using char pointer


Hello I writing a program to execute commands from the text file. The code below is used to store line by line into char array first.

So I expect it to do something like

args[0]= The first line of text file  
args[1]= The second line of text file
... and so on

In my code, all of the arrays would be covered by the last array. And I can't figure out why.

Can anyone help me fix this and tell me why my code does that. Also I need to keep char *args[]. cos I would use it with execvp() later.

int main(int argc, const char * av[]) {    
    FILE *fp;    
    fp = fopen(av[1],"r");

    int n_lines=0;        
    char in[100],*args[16];        
    int size=sizeof(in);

     while(fgets(in, size, fp)!=NULL){        
        args[n_lines] = in;                
        printf("Args[0] is %s\n",args[0]);            
        n_lines++;
    }

     printf("Now Args[0] is %s\n",args[0]);
}

Output

zacks-MacBook-Pro:prac2 zack$ ./a.out test    
Args[0] is ./addone    
Args[0] is ./add    
Now Args[0] is ./add

Solution

  • int n_lines=0;        
    char in[100],*args[16];        
    int size=sizeof(in);
    
    while(fgets(in, size, fp)!=NULL){        
        args[n_lines] = in;                
        printf("Args[0] is %s\n",args[0]);            
        n_lines++;
    }
    

    The value of in is overwritten on each iteration, you need to reserve space (using malloc->strcpy or strdup if available):

    char in[100], *args[16];
    
    while (fgets(in, sizeof in, fp) != NULL) {
        args[n_lines] = strdup(in);
        ...
        n_lines++;
    }
    

    Or use a 2D array (an adjust of sizeof is required in fgets):

    char in[16][100];
    
    while (fgets(in[n_lines], sizeof in[0], fp) != NULL) {
        ...
        n_lines++;
    }
    

    And as pointed out by @MichaelWalz in comments: you'll run into problems if your file has more then 16 lines.

    Change to

    while (fgets(in[n_lines], sizeof in[0], fp) != NULL) {
        ...
        if (++n_lines == (sizeof in / sizeof in[0])) break;
    }