-1

I have data files, one of them look like this :

enter image description here

All the files have "NA"s in them. I need to read these files and find average of the numbers on second column ignoring the "NA" ones. I want to write a C code. I have made a test data file that looks like this :

enter image description here

And I wrote this test code :

       #include<stdio.h>
       int main()
       {
        FILE *f = fopen("a.txt", "r");
        int num1, num2;
        int i;
        char c;
        int count = 0;
        double avg = 0.0;
        c = fgetc(f);
        while(c = fgetc(f) != EOF)
        {
          if(c != 'N' || c != 'A')
          {
            fscanf(f, "%d %d", &num1, &num2);
            count += 1;
            avg = avg + num2;
            printf("%d\n", num2);
           }
          }
       fclose(f);
       avg = avg/count;
       printf("Avg = %g\n", avg);

     }

This code does not give the desired output. So what I want is num2 (the second column of the data file) for the above data file to look like this, ignoring the "NA" :

1
9
16

How to write C code to perform this task?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • 2
    Fyi, `while(c = fgetc(f) != EOF)` - I suspect you don't understand the actual [operator precedence](http://en.cppreference.com/w/c/language/operator_precedence) taking place in that conditional. You're going to need another pair of parens. Further, `if(c != 'N' || c != 'A')` - that conditional is *always* true. If `c` is anything *other* than 'N' or 'A', it is obviously true, and if it is one of those, then it isn't the other, thereby also making it true. I suspect you meant `&&`, not `||`. – WhozCraig Jul 29 '17 at 19:56
  • 3
    Please post *a few* representative examples of your input as text **in the question** - not as an image link. – Weather Vane Jul 29 '17 at 20:00
  • If you read each line with `fgets` you can examine it at your leisure. – Weather Vane Jul 29 '17 at 20:03
  • `while(fgets(lineBuffer, sizeof lineBuffer, f)){ retv=sscanf(lineBuffer, "%d %lf", &intNum, &doubleNum); ...` – BLUEPIXY Jul 29 '17 at 20:04
  • 1
    There are so many mistakes/oversights in the code, I suspect you need help from a tutor. – Weather Vane Jul 29 '17 at 20:26
  • [`fgetc` returns an *int*](https://stackoverflow.com/a/35356684/918959) – Antti Haapala -- Слава Україні Jul 29 '17 at 21:09
  • Also, never post screenshots - but actual copy-paste of even the file data! – Antti Haapala -- Слава Україні Jul 29 '17 at 21:10

1 Answers1

0

There are some issues in your code as already mentioned in the comments. The main (conceptual) thing I see is that you read in single characters with fgetc (and do some tests) and then use fscanf. For me it is not clear what you intend with that mixture; maybe you mix up fgetc and fgets.

Anyway, if the file contains solely lines with two columns, you could get ahead with a loop of single fscanf-statements reading in two values. To distinguish NA from real values, you could read in the value as a string first and convert it only if it is not equal to "NA". See the following code illustrating this approach. Note the "%*d", which consumes an integral value but does not store it (as indicated by the * in the format). So fscanf("%*d %s",...) will return 1 if it could skip an integral value and if it could read in a string value. Note further that "%s" skips any leading white spaces, such that you can actually compare the value to "NA":

int main(){

    FILE *f = fopen(DATAFILE,"rt");
    if (f) {
        char valueStr[100];
        double sum = 0;
        int count = 0;
        while (fscanf(f,"%*d %99s", valueStr) == 1) {
            if (strncmp(valueStr,"NA",2)==0)
                continue;

            double value = strtod(valueStr, NULL);
            sum += value;
            count++;
        }
        printf("scanned %d valid lines; average: %lf\n", count, sum/count);
    }
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58