Home > other >  How to add strtok token read from file into array?
How to add strtok token read from file into array?

Time:10-30

int main(){
    FILE *file;
    char line[100];
    char name[26],code[4],donator[10],shipment[10], quantity[10];
    int count = 0;

    file = fopen("donation.txt","r");

    if(!file){
        printf("File does not exist!");
        return 1;
    }

    while (!feof(file)){
        fgets(line,100,file);
        count  ;
    }
    char *list[count][5];
    memset(list,0,sizeof(list));

    fseek(file,0,SEEK_SET);
    count=0;

    int count2=0;
    char dtm[sizeof(line)];
    while (!feof(file)){
        fgets(line,100,file);
        if (count>0){
            strcpy(dtm,line);
            printf("%s",dtm);
            count2=0;
            for(char  *p = strtok(dtm,"|");p ; p=strtok(NULL,"|")){
                printf("\n %d %s",count2,p);
                list[count-1][count2]=p;
                printf("\n%s",list1[count-1][count2]);
                count2  ;
            }
        }
        count  ;
    }
    for(int i =0; i<count-1 ;i  ){
        for(int k=0;k<count2;k  )
            printf("\n%d %d %s",i,k,list[i][k]);
    }
    fclose(file);
    return 0;
}

.

Contactless Thermommeter | CT          | Japan        | 1               | 1                      
Hand Sanitizer           | HS          | USA          | 1               | 1                      
Face Mask                | FM          | China        | 1               | 1                      
Surgical Mask            | SM          | China        | 1               | 1                      
Oxygen Mask              | OM          | Saudi Arabia | 1               | 1                                               

for loop's expected output snippet:

0 0 Contactless Thermometer<br/>
0 1  CT<br/>
0 2  Japan<br/>
0 3  1<br/>
0 4  1<br/>
1 0 Hand Sanitizer<br/>
1 1  HS<br/>
1 2  USA<br/>
1 3  1<br/>
1 4  1<br/>

for loop's output snippet:

0 0 Oxygen Mask<br/>
0 1  OM<br/>
0 2  Saudi Arabia<br/>
0 3  1<br/>
0 4  1<br/>
1 0 Oxygen Mask<br/>
1 1  OM<br/>
1 2  Saudi Arabia<br/>
1 3  1<br/>
1 4  1<br/>

I just started C after learning Python in my pre-U and I am very grateful if anyone here can guide me on what went wrong with my code. In the file reading process, I used strtok to break down the lines in the txt file and store in list[i][k], as shown in How to store tokens(strtok) in a pointer on an array. It shows the intended value but in the next for loop, list[i][k] only showed the last set of values as the picture below.

CodePudding user response:

Ok, the code is a bit messy, you simply want to map your file in a 2D array.

There are several troubles :

    if (count>0){

Why ? You want to have every lines in your array, don't skip the first one.

            list[count-1][count2]=p;

Skip the -1. It has nothing to do there.

            list[count-1][count2]=p;

Yes, two problems in the same line.

You assign in your array a pointer on a string that will change. And pointer aliasing. strtok returns a pointer to the actual string. It does not reallocate memory.

The solution is simply to strdup your string, so it has a fresh new memory that is not going to be changed on the next loop cycle.

            list[count][count2] = strdup(p);

Don't forget to free that later. Don't forget to check if your strdup did not fail :)

Other notes : You have unused variables. The newline remains in the string, in the last token. You may want to remove that.

CodePudding user response:

strtok() returns a pointer into the original array, this array will be overwritten by the next call to fgets() so you should allocate a copy of the string. You can use strdup() for that:

    list[count][count2] = strdup(p);

Also note that while (!feof(file)) is not a reliable way to test if another line is available from the file. You should just call fgets() and check the return value:

    while (fgets(line, 100, file)) { ...

Here is a modified version:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
    FILE *file;
    char line[100];
    char name[26], code[4], donator[10], shipment[10], quantity[10];
    int count = 0;

    file = fopen("donation.txt", "r");
    if (!file) {
        printf("File does not exist!");
        return 1;
    }

    /* count the number of lines */
    while (fgets(line, sizeof line, file)) {
        count  ;
    }

    /* allocate the 2D array of tokens and the per line token counts 8/
    char *list[count][5];
    int listlen[count];

    /* restart parsing at the beginning of the file */
    fseek(file, 0, SEEK_SET);
    count = 0;

    while (fgets(line, sizeof line, file)) {
        count2 = 0;
        /* split the line on |, also stripping the trailing newline
         * note however that strtok() does not allow for empty tokens */
        for (char *p = strtok(line, "|\n"); count2 < 5 && p != NULL; p = strtok(NULL, "|\n")) {
            list[count][count2] = strdup(p);
            count2  ;
        }
        listlen[count] = count2;
        count  ;
    }
    for (int i = 0; i < count; i  ) {
        for (int k = 0; k < listlen[count]; k  )
            printf("%d %d %s\n", i, k, list[i][k]);
    }
    fclose(file);
    return 0;
}
  •  Tags:  
  • c
  • Related