specyfikatorem %f
konwersja mówi scanf
przestać czytać wejście tak szybko, jak to widzi znak, który nie jest częścią prawnej zmiennoprzecinkowej stałej (czyli coś, co nie jest cyfra, przecinek, lub znak). Ten zły znak zostaje pozostawiony w strumieniu wejściowym, więc następne wywołanie do scanf
kończy się niepowodzeniem, a następne i następne itd.
Powinieneś zawsze sprawdzić wartość zwracaną przez scanf
- dowiesz się, ile elementów było poprawnie odczytane i przypisane ze strumienia wejściowego. W tym przypadku spodziewamy się pojedynczego elementu, więc powinieneś otrzymać wartość zwracaną równą 1. Jeśli otrzymasz wartość 0, oznacza to, że dane wejściowe nie są poprawną wartością zmiennoprzecinkową i że złe wejście musi być jakoś oczyszczonym. Oto jeden z możliwych rozwiązań:
if (scanf("%f", &minutes) == 1)
{
// process minutes as normal
}
else
{
// clear everything up to the next whitespace character
while (!isspace(getchar()))
; // empty loop
}
Jedyny problem polega na tym, że scanf
jest trochę głupie, a jeśli wpiszesz coś jak 123fgh
, to konwersję i przypisać 123
pozostawiając fgh
w strumieniu wejściowym; prawdopodobnie chcesz całkowicie odrzucić cały wkład.
Jednym z rozwiązań jest odczytać dane wejściowe jako tekst, a następnie przekształcić go za pomocą strtod
:
char buffer[BUFSIZE]; // where BUFSIZE is large enough to handle expected input
...
if (fgets(buffer, sizeof buffer, stdin))
{
char *chk; // chk will point to the first character *not* converted; if
// it's anything other than whitespace or the string terminator,
// then the input was not a valid floating-point value.
double tmp = strtod(buffer, &chk);
if (isspace(*chk) || *chk == 0)
{
minutes = tmp;
}
else
{
// input was not a proper floating point value
}
}
Ma to tę zaletę, nie pozostawiając bzdura w strumieniu wejściowym.
Co zamierzacie z tym programem? Co masz na myśli z minutami negatywnymi i pozytywnymi? – user3078414
Zauważ, że 'scanf' nie jest najbezpieczniejszym sposobem uzyskania danych wejściowych, szczególnie, gdy chcesz obsłużyć różne możliwości wprowadzania danych. Zobacz zaakceptowaną odpowiedź [tutaj] (http://stackoverflow.com/questions/2430303/disadvantages-of-scanf) – iRove
Dlaczego tytuł jest sformułowany tak, jakby był to błąd w C? – cat