2009-09-15 19 views
20

Korzystam z następującego kodu C, aby wprowadzić dane wejściowe od użytkownika, dopóki nie wystąpi EOF, ale problem jest ten kod nie działa, kończy się po pierwszym wprowadzeniu. Czy ktoś może mi powiedzieć, co jest nie tak z tym kodem? Z góry dziękuję.Wykrywanie EOF w C

float input; 

printf("Input No: "); 
scanf("%f", &input); 

while(!EOF) 
{ 
    printf("Output: %f", input); 
    printf("Input No: "); 
    scanf("%f", &input); 
} 
+3

Uwaga: Przy założeniu, że dane wejściowe użytkownika nie jest wyprowadzony, sprawdzanie EOF prawdopodobnie nie jest idealna, ponieważ IIRC zwykle oznacza to, że użytkownik musi naciśnij ctrl + D, aby zamknąć, co jest nieoczywiste – Brian

Odpowiedz

40

EOF tylko makro o wartości (zwykle 1). Musisz przetestować coś przeciwko EOF, takie jak wynik połączenia getchar().

Jednym ze sposobów sprawdzenia końca strumienia jest funkcja feof.

if (feof(stdin)) 

uwaga, że ​​„koniec strumienia” stan zostanie ustawiony tylko po nieudanej czytać.

W twoim przykładzie powinieneś sprawdzić wartość zwracaną przez scanf i jeśli to wskazuje, że nie przeczytano żadnych pól, sprawdź koniec pliku.

+2

Dzięki Charles Bailey. – itsaboutcode

+3

Zwróć uwagę na komentarz Briana: stdin zwykle nie rejestruje EOF, ponieważ zawsze można wpisać więcej. W systemie Unixy oznacza to zwykle control-D. –

+0

Zależy od tego, co masz na myśli "normalnie". Jeśli przekierowałeś stdin (plik lub potok, unix lub windows), EOF jest zwykle sygnalizowany poprawnie. W interaktywnym terminalu unixowym^D zwykle działa, w trybie tekstowym Windows działa^Z na początku linii. –

8

jest stałą w C. Nie sprawdzasz aktualnego pliku dla EOF. Trzeba to zrobić w ten sposób:

while(!feof(stdin)) 

Oto dokumentacja dla feof. Możesz także sprawdzić wartość zwracaną przez scanf. Zwraca liczbę pomyślnie skonwertowanych elementów lub EOF, jeśli osiągnie koniec pliku.

+0

czy funkcja PLIK zawiera zmienną, która byłaby lepsza do przetestowania niż użycie EOF? wydaje się, że lepiej byłoby sprawdzić status na rzeczywistym wskaźniku pliku, niż użyć dziwnej funkcji, która działa tylko przez połowę czasu. – MarcusJ

0

jako punkt wyjścia można spróbować wymienić

while(!EOF) 

z

while(!feof(stdin)) 
4

Innym problemem jest to, że czytasz tylko scanf("%f", &input);. Jeśli użytkownik wpisze coś, co nie może być zinterpretowane jako liczba zmiennoprzecinkowa C, np. "Pi", wywołanie scanf() nie spowoduje przypisania niczego do input i nie będzie się z tego dalej rozwijać. Oznacza to, że próbowałoby kontynuować czytanie "pi", a także nie.

Po zmianie na inne plakaty, które zalecają inne plakaty, wpisanie "pi" spowoduje niekończącą się pętlę drukowania poprzedniej wartości input i drukowania monitu, ale program nigdy nie przetworzy żadnego nowego wkład.

scanf() zwraca liczbę przydziałów wprowadzonych zmiennych wejściowych. Jeśli nie przydzieliło zadania, oznacza to, że nie znalazło liczby zmiennoprzecinkowej, i powinieneś przeczytać więcej danych wejściowych z czymś takim jak char string[100];scanf("%99s", string);. Spowoduje to usunięcie następnego ciągu ze strumienia wejściowego (w każdym razie do 99 znaków - dodatkowy char jest dla terminatora o wartości NULL w łańcuchu).

Wiesz, to przypomina mi o wszystkich powodach, dla których nienawidzę scanf(), i dlaczego używam zamiast tego fgets(), a następnie może analizować je za pomocą sscanf().

-1

Chcesz sprawdzić wynik scanf(), aby upewnić się, że nastąpiła pomyślna konwersja; jeśli nie było, to jedna z trzech rzeczy jest prawdą:

  1. scanf() jest dławiąc się znak, który nie jest ważny dla konwersji specyfikatorem% F (czyli coś, co nie jest cyfrą, kropka, "e" lub "E");
  2. scanf() wykrył EOF;
  3. scanf() wykrył błąd podczas odczytu stdin.

Przykład:

int moreData = 1; 
... 
printf("Input no: "); 
fflush(stdout); 
/** 
* Loop while moreData is true 
*/ 
while (moreData) 
{ 
    errno = 0; 
    int itemsRead = scanf("%f", &input); 
    if (itemsRead == 1) 
    { 
    printf("Output: %f\n", input); 
    printf("Input no: "); 
    fflush(stdout); 
    } 
    else 
    { 
    if (feof(stdin)) 
    { 
     printf("Hit EOF on stdin; exiting\n"); 
     moreData = 0; 
    } 
    else if (ferror(stdin)) 
    { 
     /** 
     * I *think* scanf() sets errno; if not, replace 
     * the line below with a regular printf() and 
     * a generic "read error" message. 
     */ 
     perror("error during read"); 
     moreData = 0; 
    } 
    else 
    { 
     printf("Bad character stuck in input stream; clearing to end of line\n"); 
     while (getchar() != '\n') 
     ; /* empty loop */ 
     printf("Input no: "); 
     fflush(stdout); 
    } 
} 
+1

możliwe nieskończoną pętlę przy czyszczeniu do końca linii. Proponuję '' while while (((ch = getchar())! = EOF) && (ch! = '\ N'))/* void * /; '' ad następnie sprawdź (ponownie) dla EOF i ustawienia '' moredata = 0; '' – pmg

+0

Proszę otworzyć nowe pytanie. – andig

-2
while(scanf("%d %d",a,b)!=EOF) 
{ 

//do ..... 
} 
+0

Zrobiłem to za pomocą .... –

+0

whats wrong:/i nie rozumiem –