Reputation: 45
I am making an application that needs to be able to load data from a text file that is formatted in a specific way. For example...
James, 2, 7.000000, 1000.000000, 0.000000, 0.000000
Tony, 7, 7.000000, 1000.000000, 0.000000, 0.000000
Michael, 2, 7.000000, 1000.000000, 0.000000, 0.000000
David, 2, 7.000000, 1000.000000, 0.000000, 0.000000
Currently, I am trying to make it so that my program reads the file and outputs in the console
1. James
2. Tony
3. Michael
4. David
I tried the following in an attempt to do this...
(The structure I was using to store data)
struct userSession {
char name[20];
int unitType;
float amountPaid;
float amountPurchased;
float returnInvestment;
float personalAmount;
float personalPercent;
};
In the main()
FILE *fp;
struct userSession user;
int counter = 1;
if( (fp = fopen("saves.dat", "r")) == NULL ) {
puts("File cannot be opened!");
}
else {
while(!feof(fp)) {
fscanf(fp, "%[^ \t\n\r\v\s,]%*c %d %f %f %f %f", &user.name, &user.unitType, &user.amountPurchased, &user.amountPaid, &user.personPercent, &user.returnInvestment);
printf("%d. %s\n", counter, user.name);
counter++;
}
}
This results in an infinite while loop. I am assuming that nothing is making read past the first file, therefore never reaching the EOF, but I may be wrong.
Can anyone offer some insight to how this may be accomplished? I have read up on fseek/fwrite/fread, but they dont seem to output/input plain text, such as the input file i'd be working with.
Ultimately, once I have this list working, the user would be prompted to select from the list to load the desired data.
Thanks, Cam
Upvotes: 2
Views: 71
Reputation: 8286
Since the fields are separated by commas, this could be used. fscanf will return the number of fields successfully read.
the 19 will prevent writing too many characters into the name
the space before %19 in " %19
will skip the newline left from previous lines
since user.name
is an array, the ampersand is not needed
while( ( fscanf(fp, " %19[^,], %d, %f, %f, %f, %f", user.name, &user.unitType, &user.amountPurchased, &user.amountPaid, &user.personPercent, &user.returnInvestment)) == 6) {
printf("%d. %s\n", counter, user.name);
counter++;
}
Even better as mentioned in another answer by @ameyCU, now deleted??
Use fgets to read each line from the file then sscanf to get the fields.
char line[100];//or larger if needed
while ( fgets ( line, sizeof ( line), fp)) {
if ( ( sscanf(fp, "%19[^,], %d, %f, %f, %f, %f", user.name, &user.unitType, &user.amountPurchased, &user.amountPaid, &user.personPercent, &user.returnInvestment)) == 6) {
printf("%d. %s\n", counter, user.name);
counter++;
}
}
Upvotes: 1
Reputation: 12272
I think you have to use fscanf()
in place of scanf()
.
fscanf(fp, "%[^ \t\n\r\v\s,]%*c %d %f %f %f %f", &user.name, &user.unitType, &user.amountPurchased, &user.amountPaid, &user.personPercent, &user.returnInvestment);
Upvotes: 2