Josh Josh - 9 days ago 10
C Question

Scanning through a file in C

So I have the following in my text document:

7
PERSON Sarah 20 5 50
PERSON Jordan 30 10 30
PERSON James 25 42 56.50
GROUP STEEL 2
Martin 21 5 80.50
Martha 25 10 79.75
PERSON Hector 38 10 100.50
PERSON Charles 18 5 35
GROUP LUMBER 3
Jill 19 5 91
Aaron 25 10 98
Mark 28 42 152.80


So I'm trying to get my code to loop through all of the names here and print out info. The name represents the person's name, the first number represents age, the second number represents kilometers ran, and the third number represents amount raised. PERSON represents an individual person, whilst group represents multiple individuals. The 7 in the first line represents the total number of PERSONS and GROUPS; there are 5 people labeled PERSON and 2 groups labeled GROUP.

However, my code is only printing out the information for everyone with the label of PERSON. How can I get my code to print the name of the group along with the information for its members? Here is my code (not completely, but to show what I'm trying to do):

FILE * ifp = fopen("race01.txt", "r");
int numPeople, i, num = 1;
struct person individual;

fscanf(ifp, "%d", &numPeople);

for(i = 0; i < numPeople; i++) {
fscanf(ifp, "%s %s %d %d %f", individual.name, individual.name, &individual.age, &individual.event, &individual.money);

if (individual.event == 42) {
printf("%s registered for the marathon race! They have been assigned the number %d\n", individual.name, num);
}
else {
printf("%s registered for the %dk race! They have been assigned the number %d\n", individual.name, individual.event, num);
}

num++;
}


I've tried all sorts of variations, from a nested for loop to additional scanning line, but nothing seems to cover the "groups".

Answer

As Jonathan said you should check if the first string you read is "PERSON" or "GROUP". If it equals "PERSON", you read information (name, age etc...) about this person, if it equals "GROUP", you should read the number of persons in that group and then read information about each person present in that group. Use functions like "strcmp" to compare two strings. I have a modified version of your code below, it compiles and works fine. I created a function named "print_raceinfo" which prints information about a person

#include<stdio.h>
#include<math.h>

#define NAME_MAX 25

struct person {
   char name[NAME_MAX];
   int age;
   int event;
   float money;
};

void print_raceinfo(struct person individual, int num)
{
    if (individual.event == 42) {
        printf("%s registered for the marathon race! They have been assigned the number %d\n", individual.name, num);
    }
    else {
        printf("%s registered for the %dk race! They have been assigned the number %d\n", individual.name, individual.event, num);
    }
}

int main(){

    FILE *fp;
    int numPeople, i, num = 1;
    struct person individual;
    char person_or_group[NAME_MAX];
    char group_name[NAME_MAX];
    int numpeople_in_group, j;

    fp = fopen("F://repoexample/race.txt", "r+");
    fscanf(fp, "%d", &numPeople);

    for(i = 0; i < numPeople; i++) {

        fscanf(fp, "%s", person_or_group);

        //Compare the first 6 characters of string person_or_group with "PERSON"
        if (strncmp(person_or_group, "PERSON", 6) == 0) {

            fscanf(fp, "%s %d %d %f", individual.name, &individual.age, &individual.event, &individual.money);

            print_raceinfo(individual, num);

            num++;
        }
        else if (strncmp(person_or_group, "GROUP", 5) == 0){

                //Read group name and number of people in that group
                fscanf(fp, "%s %d", group_name, &numpeople_in_group);

                for (j = 0; j<numpeople_in_group; j++) {

                    //Extract information for each person in that group
                    fscanf(fp, "%s %d %d %f", individual.name, &individual.age, &individual.event, &individual.money);

                    print_raceinfo(individual, num);

                    num++;
                }
        }

   }

    printf("Total number of persons = %d\n", num - 1);

    return 0;
}

Output: SEE OUTPUT

Comments