8

i have to write a program in C to read a file containing several line of text, each line contains two variables: a number (%f) and a string:

EX: file.txt
============
24.0 Torino
26.0 Milano
27.2 Milano
26.0 Torino
28.0 Torino
29.4 Milano

There is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (int argc, char *argv[])
{
    int r, line = 0, found = 0;
    float temp, t_tot = 0;
    char loc[32];


    FILE *fp;

    fp = fopen(argv[1], "r");

    if (fp == NULL)
    {
        printf ("Error opening the file\n\n'");
        exit(EXIT_FAILURE);
    }

    if (argc == 3)
    {
        r = fscanf(fp, "%f %s\n", &temp, loc);

        while (r != EOF)
        {
            line++;

            if (r == 2)
            {
                if(strcmp(argv[2], loc) == 0)
                {
                    t_tot += temp;
                    found++;
                }
            }
            else
                printf ("Error, line %d in wrong format!\n\n", line);
        }

        printf ("The average temperature in %s is: %.1f\n\n", argv[2], (t_tot/found);
    }

}

The program needs to read all the line and find the city i wrote on argv[2]. Than it will tell me the average temperature on that city, notifying me if a line in the file is in a wrong format.

The program is compiling correctly to me but it not output anything on screen... how can i solve that? Is it correct to use fscanf on this case or it's better fgets?

I'm a student so, please, give me an "academical" way to resolve it :)

Lc0rE
  • 2,236
  • 8
  • 26
  • 34

4 Answers4

13

A couple of things.

First, you gotta use fclose().
Second, your code needs to fscan() each line in the file. Not just before the while() loop, but within each while loop you gotta fscan() for the next iteration.
Third, you weren't figuring the average temperature, you're figuring the sum of all the tempuratures found. Fix that by changing "t_tot" to "(t_tot / found)" in your last printf().

Lastly, I'm not sure why you're not getting any output. Your input is like "myprogram file.txt Milano" right? Works for me. Anyway, here's your (edited) code back:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (int argc, char *argv[])
{
    int r, line = 0, found = 0;
    float temp, t_tot = 0;
    char loc[32];

    FILE *fp;
    fp = fopen(argv[1], "r");

    if (fp == NULL)
    {
        printf ("Error opening the file\n\n'");
        exit(EXIT_FAILURE);
    } else {

        if (argc == 3)
        {
            r = fscanf(fp, "%f %s\n", &temp, loc);
            while (r != EOF)
            {
                line++;
                if (r == 2)
                {
                    if(strcmp(argv[2], loc) == 0)
                    {
                        t_tot += temp;
                        found++;
                    }
                }
                else
                    printf ("Error, line %d in wrong format!\n\n", line);
                r = fscanf(fp, "%f %s\n", &temp, loc);
            }
            printf ("The average temperature in %s is: %.1f\n\n", argv[2], (t_tot / found));
        }

    fclose(fp);

    }
}
dogglebones
  • 387
  • 1
  • 8
3

Your code does not call fscanf in the loop like it should: the read is done once, and then the program either exists right away if the file is empty, or loops indefinitely.

You should move the call of fscanf inside the while loop. One typical way of coding it is placing the assignment inside the loop header, like this:

while ((r = fscanf(fp, "%f %s\n", &temp, loc)) != EOF) {
    ...
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thank You for your answer. I just realize my error! If i wanted to make another solution with fgets instead of fscanf, how could i do this? – Lc0rE Jun 23 '12 at 10:13
  • 1
    @l_core You'd need to change a few things: first, you'd need a buffer for `fgets`; then you'd replace the check for `EOF` with a check for `NULL` in the loop; finally, you'd need to parse the buffer manually, by finding the first space, feeding the initial part to `atof`, and copying the rest in `strdup`. – Sergey Kalinichenko Jun 23 '12 at 10:18
3

you must put fscanf line inside the while loop

    while (1)
    {
        r = fscanf(fp, "%f %s\n", &temp, loc);
        if( r == EOF ) 
           break;
        .........................
    }

finally close the file

if u are using fgets change as follows

  char s[256];
  while( fgets( s, 256, fp) != NULL )
  {
     sscanf( s, "%f %s", &temp, loc);
     .............
  }
Riskhan
  • 4,434
  • 12
  • 50
  • 76
1

modify the code like this... just put another fscanf in while statement.

if (argc == 3)
{
 r = fscanf(fp, "%f %s\n", &temp, loc);
  while(r != EOF )

    {
        r = fscanf(fp, "%f %s\n", &temp, loc);  
        line++;

        if (r == 2)
        {
            if(strcmp(argv[2], loc) == 0)
            {
                t_tot += temp;
                found++;
            }
        }
        else
            printf ("Error, line %d in wrong format!\n\n", line);
    }

    printf ("The average temperature in %s is: %.1f\n\n", argv[2], t_tot);
}

}
Ritesh Chandora
  • 8,382
  • 5
  • 21
  • 38