Cam
Cam

Reputation: 45

Getting line to line input from formatted text file

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

Answers (2)

user3121023
user3121023

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

Haris
Haris

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

Related Questions