Zabezpieczenie przed wpisywaniem liter
Bardzo często na forum pojawia się pytanie: jak zabezpieczyć program przed wpisaniem liter, gdy program oczekuje na liczby.
Najprostsze rozwiązanie w języku C++ wygląda tak:
W języku C nie istnieje równie proste rozwiązanie tego problemu. Można spróbować użyć:
Ale nie jest to dobre rozwiązanie, ponieważ jest zależne od implementacji. fflush() nie zawsze powoduje wyczyszczenie bufora!
Rozwiązanie działające w każdej sytuacji (i implementacji) polega na żmudnym wyciągnięciu z stdin zalegających tam, zbędnych znaków (dodatkowa pętla w miejscu fflush())
Najprostsze rozwiązanie w języku C++ wygląda tak:
int zmienna;
while(!(cin>>zmienna)) //dopóki strumień jest w stanie błędu -> dopóki podawane są błędne dane
{
//ew komunikat błędu
cin.sync(); //kasowanie zbędnych znaków z bufora
cin.clear(); //kasowanie flagi błędu strumienia
}
//tutaj na pewno wczytano poprawne dane do zmienna
while(!(cin>>zmienna)) //dopóki strumień jest w stanie błędu -> dopóki podawane są błędne dane
{
//ew komunikat błędu
cin.sync(); //kasowanie zbędnych znaków z bufora
cin.clear(); //kasowanie flagi błędu strumienia
}
//tutaj na pewno wczytano poprawne dane do zmienna
W języku C nie istnieje równie proste rozwiązanie tego problemu. Można spróbować użyć:
int zmienna;
while(scanf("%d", &zmienna) != 1) //dopóki nie uda się wczytać
{
//ew. komunikat błędu
fflush(stdin);
}
while(scanf("%d", &zmienna) != 1) //dopóki nie uda się wczytać
{
//ew. komunikat błędu
fflush(stdin);
}
Ale nie jest to dobre rozwiązanie, ponieważ jest zależne od implementacji. fflush() nie zawsze powoduje wyczyszczenie bufora!
Rozwiązanie działające w każdej sytuacji (i implementacji) polega na żmudnym wyciągnięciu z stdin zalegających tam, zbędnych znaków (dodatkowa pętla w miejscu fflush())



Parafrazując: EOF w powyższym kodzie to nie jest wartość zmiennej char, a pewne makro, które ma "specjalną wartość". Funkcja getchar() sprytnie nie zwraca nam "znaku eof" (bo takowego w ascii nie ma) a jedynie ową "specjalną wartość" kiedy natrafi na prawdziwego eof'a. Stąd też kod jest poprawny