Search code examples
cstringfilestreamscanf

How to take unknown number of string from file in C?


I have a struct storing persons' names, surnames and salaries, but the number of their names is random. For example:

list.txt

John Smith Green 1000 //He has two names
Jennifer Wilson 2000 //She has one name
Steve Adams 1500 //He has one name
James Robert Harris 1250 //He has two names
Robin Walker 1750 //He has one name

I want to store their names in person[count].name, their surnames in person[count].surname and their salaries in person[count].salary.

To do that, I wrote:

fscanf(file, "%s %s %d", person[count].name, person[count].surname, &person[count].salary)

However, problem is that if a person has two names, his second name is stored in person[count].surname, and I cannot take the surname.

How can I take the name of a person with two names in person[count].name?

For this text file:

person[0].name ==> "John Smith"

person[1].name ==> "Jennifer"

person[2].name ==> "Steve"

person[3].name ==> "James Robert"

person[4].name ==> "Robin"


Solution

  • I tried reading the file line by line, then separating it into tokens (words). I am assuming each line contains at max 10 tokens (words), and the last token is salary, the one before the last is surname and first N-2 tokens are the names of the person. So, each person could have surnames with only one word, I am assuming. Here is the code, note that I did not pay attention to memory leaks or dangling pointers etc.

    I edited the solution according to the suggestions from @ chux - Reinstate Monica

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct Person
    {
        char *name, *surname;
        int salary;
    } Person;
    
    int main()
    {
        Person persons[10];
        FILE *file = fopen("text.txt", "r");
        if (file == NULL)
        {
            printf("Error opening file!\n");
            exit(1);
        }
        // read file line by line
        char line[256];
        int person_count = 0;
        while (fgets(line, sizeof(line), file) != NULL)
        {
            char *tokens[10];
            int i = 0;
    
            tokens[0] = strtok(line, " ");
            while (tokens[i] != NULL && i < 9)
            {
                tokens[++i] = strtok(NULL, " ");
            }
    
            char name[sizeof line];
            strcpy(name, tokens[0]);
            for (int j = 1; j < i - 2; j++)
            {
                strcat(name, " ");
                strcat(name, tokens[j]);
            }
            persons[person_count].name = strdup(name);
            persons[person_count].surname = strdup(tokens[i - 2]);
            persons[person_count].salary = atoi(tokens[i - 1]);
            person_count++;
        }
        for (int i = 0; i < person_count; i++)
        {
            printf("%s %s %d\n", persons[i].name, persons[i].surname, persons[i].salary);
        }
    
        fclose(file);
    }