Search code examples
cscanfformat-specifiers

fscanf not scanning any numbers


I am currently developing a simple C application. It takes a single file as a command line argument, which is formatted like:

1,2,3
4,5,6
7,8,9
etc.

However, for whatever reason, fscanf never scans the numbers! Here is an example:

#include <stdio.h>

int main(int argc, char **argv) {
    FILE *file = fopen(*argv, "r");
    int i1, i2, i3;
    while (fscanf(file, "%d,%d,%d", &i1, &i2, &i3) == 3) {
        printf("Doing stuff with %d, %d, and %d...\n", i1, i2, i3);
    }
    fclose(file);
    return 0;
}

If you run it with the filename as an argument, then it immediately exits, due to fscanf returning 0. I've tried several variations of this, to no avail. How do I make fscanf read the numbers correctly?


Solution

  • Superficial answer: wrong file was opened as code should have used argv[1] rather than *argv.

    Let us look deeper.

    Code had troubles and lacked error checking in at least 2 places.

    1. FILE *file = fopen(*argv, "r"); was not followed by a test on file. This classic check would not have detected OP's problem as the file, the executable, was open-able.

    2. The return value from fscanf(file, "%d,%d,%d", &i1, &i2, &i3) was only lightly tested. Return values of EOF 0 1 2 3 were possible yet only EOF 3 were expected. Had code tested for non-EOF 3, the problem would have rapidly been found.

    Lesson to be learned: Insure code, especially mis-behaving code, has adequate error checking. Saves the coder time in the long run.

    #include <stdio.h>
    
    int main(int argc, char **argv) {
      if (argc != 2) {
        fprintf(stderr, "Unexpected argument count %d.\n", argc);
        return 1;
      } 
      FILE *file = fopen(argv[1], "r");
      if (file == NULL) {
        fprintf(stderr, "Unable to open file: \"%s\"", argv[1]);
        return 1;
      } 
      int i1, i2, i3;
      int n;
      while ((n = fscanf(file, "%d,%d,%d", &i1, &i2, &i3)) == 3) {
        printf("Doing stuff with %d, %d, and %d...\n", i1, i2, i3);
      }
      if (n != EOF) {
        fprintf(stderr, "Unexpected scan failure count %d\n", n);
        return 1;
      }
      fclose(file);
      return 0;
    }