I am having trouble with the ReadPersonData function. I need to read in data from a and store the data in structure arrays.
Data looks like this: Name, Country, City, Street, Hobby count, Hobbies
John Brazil Brasilia Esplanada 1 Reading
Mary Japan Tokyo Harajuku 2 Painting Swimming
David Australia Canberra Northbourne 3 Running Gardening Cycling
Sarah Norway Oslo Storgata 2 Cooking Fishing Writing Dancing
James Mexico Tijuana Insurgentes 5 Reading Painting Running Swimming Cycling
Jennifer Egypt Cairo Ramses 6 Cooking Painting Dancing Swimming Reading Writing
Michael Canada Ottawa Wellington 7 Running Fishing Cycling Reading Painting Writing Swimming
Jessica Estonia Tallinn Keskuse 8 Cooking Dancing Reading Painting Swimming Running Writing Gardening
Robert Argentina Rosario Corrientes 9 Running Cycling Reading Swimming Painting Writing Fishing Cooking Dancing
Amanda Germany Berlin Alexanderplatz 10 Reading Painting Running Swimming Gardening Cooking Fishing Cycling Writing Dancing
I am having trouble reading in the hobbies. It will read in the hobbies until the hobby count goes from 3 to 2, then it stops reading in data, probably because in the cycle
for(i = 0; i < personList[persons.hobbyCount; i++) , i is now bigger than a persons hobby count. I want it to keep on reading data, but I just can’t figure it out.
Since English is not my first language I don’t know how to search for solutions on this particular topic and ChatGPT is not helping so now here I am. How do I fix my problem?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME_LEN 32
#define MIN_HOBBIES 0
#define MAX_HOBBIES 10
#define MAX_PERSONS 100
#define MAX_FILE_NAME_SIZE 16
#define ARG_CNT 2
#define ARG_EXEC_NAME argv[0]
#define ARG_FILE_NAME argv[1]
typedef struct
{
char country[MAX_NAME_LEN];
char city[MAX_NAME_LEN];
char street[MAX_NAME_LEN];
} address;
typedef struct
{
char name[MAX_NAME_LEN];
address residence;
int hobbyCount;
char hobbies[MAX_HOBBIES][MAX_NAME_LEN];
} person;
int ReadPersonData(person personList[] , int limit, char *fName);
void FindSameHobby(person personList[], int personCount, char hobbyName[]);
void OutPutData(person personList[], int personCount, char hobbyName[]);
int main(int argc, char **argv)
{
if(argc != ARG_CNT)
{
fprintf(stderr, "Usage: %s input_file\n", ARG_EXEC_NAME);
return EXIT_FAILURE;
}
person personList[MAX_PERSONS];
int personCount = ReadPersonData(personList, MAX_PERSONS, ARG_FILE_NAME);
return 0;
}
int ReadPersonData(person personList[] , int limit, char *fName)
{
int persons = 0;
int i;
FILE *fPerson = fopen(fName, "r");
if(fPerson == NULL)
{
fprintf(stderr, "Error opening input file %s", fName);
perror(" ");
return persons;
}
while(fscanf(fPerson, "%s %s %s %s %d", personList[persons].name,
personList[persons].residence.country,
personList[persons].residence.city,
personList[persons].residence.street,
&personList[persons].hobbyCount) == 5)
{
if(personList[persons].hobbyCount < MIN_HOBBIES ||
personList[persons].hobbyCount > MAX_HOBBIES)
{
printf("ERROR! Invalid hobby count for %s, exiting now!\n",
personList[persons].name);
exit(1);
}
for(i = 0; i < personList[persons].hobbyCount; i++)
{
fscanf(fPerson, "%s", personList[persons].hobbies[i]);
}
persons++;
if(persons > limit)
{
fprintf(stderr, "ERROR! Input file is too long! ALlowed "
"limit is %d entries. Reading of the "
"file has stopped, continuing within "
"a partial dataset\n", limit);
break;
}
}
fclose(fPerson);
return persons;
}
I tried to change the cycle parameters to no avail.
>Solution :
This line has 2 extra data after 2 hobbies:
Sarah Norway Oslo Storgata 2 Cooking Fishing Writing Dancing
Therefore, after reading the hobbies (Cooking Fishing), your program will behave as if the data left is added before the next line and the next line is :
Writing Dancing James Mexico Tijuana Insurgentes 5 Reading Painting Running Swimming Cycling
Then the format specifier %d won’t accept the non-integer input Tijuana and reading stops.
One way for fixing this is skipping the extra data after hobbies like this:
for(i = 0; i < personList[persons].hobbyCount; i++)
{
fscanf(fPerson, "%s", personList[persons].hobbies[i]);
}
// add this to skip until the end of line
int c;
while ((c = getchar()) != '\n' && c != EOF);
persons++;
Note that this way doesn’t support cases where data after the hobby count is less than the hobby count or lines has other issues. To support these cases, you should use other ways like reading whole lines via fgets and parsing the lines (using strtok, for example).