2012-06-23 20 views
6

muszę napisać program w C do odczytu pliku zawierającego kilka linii tekstu, każda linia zawiera dwie zmienne: liczba (% f) oraz ciąg:Fscanf lub Fgets? Odczytywanie pliku wiersz po wierszu

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

Nie to mój kod:

#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); 
    } 

} 

Program musi przeczytać całą linię i znaleźć miasto pisałem na argv[2]. Następnie poinformuje mnie o średniej temperaturze w tym mieście, powiadamiając mnie, że linia w pliku jest w niewłaściwym formacie.

Program poprawnie się do mnie kompiluje, ale nic nie wyświetla na ekranie ... jak mogę to rozwiązać? Czy to jest poprawne użycie fscanf w tym przypadku, czy jest lepiej fgets?

Jestem studentem więc, proszę, daj mi „akademickim” sposób, aby go rozwiązać :)

Odpowiedz

11

Kilka rzeczy .

Najpierw musisz użyć funkcji fclose().
Po drugie, twój kod musi fscan() każdej linii w pliku. Nie tylko przed pętlą while(), ale w każdej pętli while musisz fscan() dla następnej iteracji.
Po trzecie, nie obliczyłeś średniej temperatury, obliczasz sumę wszystkich znalezionych tempuratures. Napraw to, zmieniając "t_tot" na "(t_tot/found)" w twoim ostatnim printf().

Wreszcie, nie jestem pewien, dlaczego nie otrzymujesz żadnych wyników. Twoje dane wejściowe są jak "myprogram file.txt Milano", prawda? Pracuje dla mnie. W każdym razie, oto twój (edytowany) kod z powrotem:

#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); 

    } 
} 
+0

Dziękuję za odpowiedź, właśnie poprawiłem swój kod. – Lc0rE

2

Twój kod nie nazywają fscanf w pętli tak jak powinien: odczyt odbywa się raz, a potem program istnieje od razu, jeśli plik jest pusty lub nieskończenie pętle.

Powinieneś przenieść wywołanie fscanf wewnątrz pętli while. Typowym sposobem kodowania jest umieszczenie wewnątrz zadanie nagłówku pętli, podobnie jak to:

while ((r = fscanf(fp, "%f %s\n", &temp, loc)) != EOF) { 
    ... 
} 
+0

Dziękuję za odpowiedź. Po prostu zdałem sobie sprawę z mojego błędu! Jeśli chciałbym zrobić inne rozwiązanie za pomocą fgetów zamiast fscanf, jak mogłem to zrobić? – Lc0rE

+1

@l_core Musisz zmienić kilka rzeczy: po pierwsze, potrzebujesz bufora dla 'fgets'; następnie zamienisz sprawdzanie dla 'EOF' z sprawdzeniem dla' NULL' w pętli; na koniec, musisz ręcznie przeanalizować bufor, znajdując pierwsze miejsce, podając początkową część 'atof' i kopiując resztę w' strdup'. – dasblinkenlight

1

zmodyfikować kod tak ... po prostu umieścić kolejną fscanf w instrukcji while.

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); 
} 

} 
3

należy umieścić fscanf linię wewnątrz pętli while

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

ostatecznie zamknąć plik

jeśli u używasz fgets zmienić następująco

char s[256]; 
    while(fgets(s, 256, fp) != NULL) 
    { 
    sscanf(s, "%f %s", &temp, loc); 
    ............. 
    } 
+0

do czego służy "1"? – Lc0rE

+1

1 oznacz zawsze prawdziwy – Riskhan

+1

zobacz moją zmienioną odpowiedź – Riskhan