Reading and Printing from a file but stuck in loop

2019-09-07 07:48发布

问题:

I'm trying to read some data from a file then print it out but My code is only reading the first content and then gets stuck in an infinite loop (in the while loop). What am I doing wrong? My output is just Student: Abby GPA: 3 I'm using Visual Studio 2012. I am just following an example from my book.

//My data is Abbie 3.4 Oakley 3.5 Sylvia 3.6 Uwe 3.7 Ken 3.8 Aaron 3.9 Fabien 4 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void main()
{    
    unsigned int GPA;//GPA
    char student[10];//Student
    FILE * cfPter;
    //Check if file opened
        if((cfPter = fopen("data.txt", "r")) ==NULL)
        {
                puts("File could not be opened");
            }
        //Read Contents
        else
            {
                puts("Contents of file:\n");
                fscanf(cfPter,"%s %f ", student, &GPA);
            }
        //While not at end Print the contents read
        while(!feof(cfPter))
        {
            printf("Student: %s GPA: %f",student,GPA);
            fscanf(cfPter, "%s %f", student, GPA);
            //system("pause");
        }

    fclose(cfPter);
    system("pause");
} //end main    

回答1:

You are getting there, but a couple of tweaks can make life easier. First, if your fopen fails, either handle the failure by prompting for another file name, or simply return (exit) at that point. That way the rest of your code isn't wrapped inside an else statement.

Next, I provided the link for why while (!feof(file)) is always wrong (when reading character data from a file). When you read input, validate you received input -- that is really all you need to do. Check the return for your fscanf call.

With that in mind, you could do something similar to the following:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main (void) {

    float GPA = 0.0;        /* GPA     */
    char student[10] = "";  /* Student */
    FILE *cfPter = NULL;

    /* open file/validate file is open */
    if (!(cfPter = fopen ("data.txt", "r"))) {
        fprintf (stderr, "error: file open failed 'data.txt'.\n");
        return 1;
    }

    /* Read Contents */
    while (fscanf (cfPter, " %9s %f", student, &GPA) == 2)
        printf ("Student: %-10s GPA: %.2f\n", student, GPA);

    fclose (cfPter);
    return 0;                   /* main is type 'int' and returns a value */
}

Example data.txt

$ cat data.txt
Abbie 3.4 Oakley 3.5 Sylvia 3.6 Uwe 3.7 Ken 3.8 Aaron 3.9 Fabien 4

Example Use/Output

$ ./bin/feofissue
Student: Abbie      GPA: 3.40
Student: Oakley     GPA: 3.50
Student: Sylvia     GPA: 3.60
Student: Uwe        GPA: 3.70
Student: Ken        GPA: 3.80
Student: Aaron      GPA: 3.90
Student: Fabien     GPA: 4.00

(note while MS will let you use void main from long ago, main is defined as type int and returns a value. )

Also to pause, you generally #include <conio.h> on windows and call getch(); to prevent the terminal window from closing. You can try it either way. Let me know if you have questions.



回答2:

I'm working on this as well, and someone told me to try using strcmp() to read the file line by line until you found the line you were looking for? I'm working with that idea but haven't figured out how it would be able to read the GPA after that.



回答3:

one plan to avoid reading different types of date in the fscanf is to always read char data into a local char array. then use sscanf to convert it to the data type you need. this allows you to add data checks between the fscanf and sscanf. this will avoid fscanf reading nothing (spinning wheels) and never getting to eof