1
#include <stdio.h>

int main()
{

    FILE *fp;
    char buffer[1001];
    char name[15], surname[30];
    float mid1, mid2, final, avg;

    fp = fopen("grades.txt", "r");
    if (!fp)
    {
        printf("Could not open file. Program finished.");
        return 0;
    }

    fgets(buffer, 1000, fp);

    while (feof(fp) == 0)
    {
        sscanf(buffer, "%s%s%f%f%f", name, surname, &mid1, &mid2, &final);

        printf("%s %s %f %f %f\n", name, surname, mid1, mid2, final);

        fgets(buffer, 1000, fp);
    }

    fclose(fp);

    return 0;
}

Here is my text file,

Ali Veli 67 80 76
Ahmet Mehmet 45 64 63
Ayse Fatma 89 98 83

all the things okay but it can't read last line of the text file in the output "Ayse Fatma 89 98 83" it can't printing.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • 3
    Looks more like C than C++. Please choose one language. Also worth a read: [Why is `while ( !feof (file) )` always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – pzaenger Jun 08 '20 at 13:03
  • 1
    Who taught you to use `while(feof(fp) == 0)`? – klutt Jun 08 '20 at 13:08
  • http://www.dgp.toronto.edu/~neff/teaching/CWebsite/fileReading.html – Batuhan Gunes Jun 08 '20 at 13:16
  • Failure to open the file would typically be considered an error. Hence, `if(!fp) {perror("grades.txt"); return EXIT_FAILURE;}`. Write the error message to stderr, include the reason, and return a failure status. – William Pursell Jun 08 '20 at 13:16
  • 2
    Although not well structured, the code should read the last line — if the data file has a newline at the end. If the final newline is missing, it is possible that `feof()` reports EOF too soon. The recommended restructuring avoids some possible pitfalls. You could also print the line that you parse to see whether there is a newline: `printf("Line: [[%s]]\n", buffer);` after the `fgets()` calls. But you should really check the result of `fgets()` before using the value in `buffer`, hence the restructured version is better (no repetition) and you'd place the `printf()` before the `sscanf()`. – Jonathan Leffler Jun 08 '20 at 14:14
  • 2
    @BatuhanGunes Good to have post [source](http://www.dgp.toronto.edu/~neff/teaching/CWebsite/fileReading.html) of weak code. Take that into consideration for other code examples. – chux - Reinstate Monica Jun 08 '20 at 14:40

1 Answers1

2

You can easily use the value that fgets returns as a condition of your while cycle:

while(fgets(buffer, sizeof(buffer), fp))
{
    if(sscanf(buffer, "%14s%29s%f%f%f", name, surname, &mid1, &mid2, &final) == 5)
        printf("%s %s %f %f %f\n",name,surname,mid1,mid2,final);
}

The cycle will stop when there are no more lines to read from the file.

Also, a good practice is to always check *scanf return.

Limiting "%s" specifiers size to their buffer is also recommended, this will avoid buffer overflow, in this case "%14s" and "%29s" for 15 char and 30 char buffer respectively, size - 1 relates to the need to reserve a space for the null terminator.

You should also follow the link in @pzaenger's comment regarding the use of while(feof(fp) == 0).

anastaciu
  • 23,467
  • 7
  • 28
  • 53