cvariablesintegeroutputfile-read

C: Reading int values from a file only results in first line of the file being read


I'm writing a function in C that reads int values from a given file and counts up by 1 every time a specified number is found. My .txt file being read has an int followed by a float on each line. However, my issue is that it only reads the first line of numbers and then breaks the loop. The part of my code that is causing the problem is this:

int tally(char fname[], int item) {
    int totalSales = 0;
    FILE *input;
    int intPlaceholder;
    FILE *write;

    input = fopen(fname, "r");

    if (input != NULL) {
        for (int i = 0; fscanf(input, "%d", &intPlaceholder) == 1; i++) {
            if (intPlaceholder == item) {
                totalSales++;
                // Adds 1 to total sales after finding a matching item code in the file
                printf("Has found a match!");
            }
            else {
                // Does nothing as it hasn't found a matching code
            }
            printf("\nLooped once.");
        }
        printf("\nStopped looping.\n");
    }
    else {
        printf("This option is not valid.\n");
        return 0;    // Could not open the file
    }
    fclose(input);
    return totalSales;
}

My current .txt file looks like this:

0   87.99
1   3.99
2   7.99
3   10.00
4   8.00

but my code above is only finding the 0 and 87 (it isn't supposed to find the 87 either but that isn't my main priority) by looping twice, when I'd expect it to loop 10 times.

I have a separate function that does the same thing with float values instead of int which works fine, I'm really confused as to why this is happening only with int values. Why is is doing this? Is there a better workaround I'm missing?


Solution

  • As I indicated in a comment, you want fscanf() to "load" both the integer and the floating point value, but only assign the integer (in this version.)

    I set up my own test data in a file name "test.txt":

    3 42.42
    3 45.58
    7 47.47
    1 78.23
    

    And here is the code (without a lot of palaver.)

    #include <stdio.h>
    
    int tally( char fname[], int item ) {
        int totalSales = 0;
    
        FILE *fp = fopen(fname, "r");
        if( fp == NULL) {
            printf("This option is not valid.\n");
            return 0;    // Could not open the file
        }
    
        int val;
        while( fscanf( fp, "%d %*f", &val ) == 1 )
            totalSales += val == item;
    
        fclose( fp );
    
        return totalSales;
    }
    
    int main( void ) {
        printf( "Test %d\n", tally( "test.txt", 3 ) );
        printf( "Test %d\n", tally( "test.txt", 7 ) );
        printf( "Test %d\n", tally( "test.txt", 4 ) );
        return 0;
    }
    

    And, here are the results:

    Test 2
    Test 1
    Test 0
    

    Using the '*' in the format specifier of fscanf(), the floating point value is "loaded" but not assigned to any variable. It should now be obvious how to sum the total of the floats without concern for the integer on the same line.