Search code examples
cstringsumtxt

How to separate numbers from strings in txt file in C?


txt file:

44.56 john doe  
100.21 jane doe

How to calculate sum of numbers? This function give 0

double get_sum(FILE *out)
{
    double sum = 0;
    double value;
    char name;
    char surname;

    while(fscanf(out, "%lf %s %s", &value, name, surname) != EOF)
    {
        sum += value;
    }
    return sum;
}

Solution

  • Just tell fscanf to ignore the name and surname slots like this:

    double get_sum(FILE *out) {
        double sum = 0;
        double value;
    
        while (fscanf(out, "%lf%*s%*s", &value) != EOF) {
            sum += value;
        }
        return sum;
    }
    

    The trouble is that you where passing pointers to char instead of a pointer to a char array that can hold the content. Since you didn't it overflowed and caused undefined behavior.

    But if you really wanted to also read in the names then try:

    double get_sum(FILE *out) {
        double sum = 0;
        double value;
        char name[5];
        char surname[4];
    
        while (fscanf(out, "%lf%s%s", &value, name, surname) != EOF) {
            sum += value;
        }
        return sum;
    }
    

    Here the buffers are just long enough to accommodate the example text files data. In real life (if you needed it) you would have the big enough to handle the longest name. The important difference to your original code is that name and surname are pointers that the fscanf function expects.

    But given that names sometimes are unpredictable in length, after reading the value on the line, just read the remaining line into a buffer and just ignore it.

    #include <assert.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    double get_sum(FILE *in) {
        double sum = 0;
        double value;
        char *remainingLine = NULL;
        size_t bufLen = 0;
    
        while (fscanf(in, "%lf", &value) == 1) {
            sum += value;
            // ignore remaining character in line
            getline(&remainingLine, &bufLen, in);
        }
        free(remainingLine);
        return sum;
    }
    
    int main(void) {
        FILE *f = fopen("text.txt", "r");
        assert(f);
        double s = get_sum(f);
        fclose(f);
        printf("Sum is %f", s);
    }
    

    with text.txt file containing

    1.03 First Surname
    2.2Here is another long "name" (sum should be 10.63)
    3.4 first middle last (next line is lonely and last)
    4
    

    Running the this last program should produce simething along the lines of

    Sum is 10.630000