Search code examples
cstringcharscanf

Values lossing in fscanf


The IDE I used is Clion. I wanna read the Line-separated data stored in .txt file. Each line contains firstname, surname, gender, ID and age, which are str, str, str, int and int.

StudentList.txt

Olivia SWANSON F 29001 20
Emma ONEILL F 7900 19

I try to use fscanf to read the data.

FILE *fp;
char fname[20];
char sname[20];
char gender[1];
int ID;
int age;
fp = fopen("C:\\Users\\Catlover\\Desktop\\DSA\\Program2\\StudentList.txt", "r");
while(fscanf(fp, "%s %s %s %d %d", fname, sname, gender, &ID, &age)!= EOF)
{
    printf("%s,%s,%s,%d,%d\n", fname, sname, gender, ID, age);
}
fclose(fp);
return 0;

But the result it return looks like a little bit weird becasue it doesn't output the second value.

Result is

Olivia,,F,29001,20
Emma,,F,7900,19

Something shocks me is that the same code runned in PellesC lead to the correct result.

I used to learn C++ so there may exists some important rules in C but I didn't notice. Can anyone show that for me?


Solution

  • "%s" without width

    Never use "%s" in a *scanf() without a width to indicate the max number of non-white-space characters to read and save. Recall that after reading, a null character is appended. Example: if the buffer size is 100, code can only read up to 99.
    char gender[1]; is too small for "F".

    Wrong check

    fscanf(fp, "%s %s %s %d %d", ...) can return other values than 5 or EOF. As only 5 is acceptable, test against that.

    Test open success

    If fopen() fails, fscanf(), fclose() are bad

    Other issues exist too*

    But lets use start with fixing the above.


    char fname[20 + 1];
    char sname[20 + 1];
    char gender[1 + 1];
    int ID;
    int age;
    FILE *fp = fopen("C:\\Users\\Catlover\\Desktop\\DSA\\Program2\\StudentList.txt", "r");
    if (fp) {
      while(fscanf(fp, "%20s %20s %1s %d %d", fname, sname, gender, &ID, &age) == 5) {
        printf("%s,%s,%s,%d,%d\n", fname, sname, gender, ID, age);
      }
      fclose(fp);
    }
    return 0;