Zadanie 2.15 nr 1.
Ostatnio zmodyfikowano 2016-07-14 06:03
CCbolt Temat założony przez niniejszego użytkownika |
Zadanie 2.15 nr 1. » 2016-07-13 20:57:30 Mam problem z zrozumieniem pewnego zagadnienia. Mój kod pierwotnie wyglądał tak(kod nr1), wszystko przy cyfrach działa idealnie jednak przy literach zapętla się w nieskończoność. W sieci znalazłem kod (kod nr 2) i podciągnąłem z niego do swojej pentli do/while komendy: cin.clear(); cin.sync(); W kodzie nr 3 na pozór wszystko gra, przy cyfrach działa poprawnie przy literach drugie zapytanie jest powtórzone dwukrotnie i dzieje się to tylko raz. Nie rozumiem czemu to się dzieje i jak się pozbyć podwójnego zapytania i jak się okazało nie rozumiem czemu cin.clear(); cin.sync(); wpływa na zamknięcie pętli zwłaszcza że w poprzednich zadaniach tych komend nie potrzebowałem. http://forum.pasja-informatyki.pl/7534/co-jest-zlego-w-tym-kodzie <<= kod nr 2 Kod nr1 #include <iostream> using namespace std;
int main() { float liczba; bool sprawdzam; cout << "Podaj liczbe: "; cin >> liczba; sprawdzam = cin.good(); if( sprawdzam == false ) { do { cout << "Podaj liczbe: "; cin >> liczba; sprawdzam = cin.good(); } while( sprawdzam == false ); } cout << "Twoja liczba to: " << liczba; return 0; }
Kod nr 2 #include <iostream>
using namespace std;
int main() { int liczba; do { cout << "Podaj liczbe:\n"; cin.clear(); cin.sync(); } while( !( cin >> liczba ) ); cout << "Twoja liczba to: " << liczba; return 0; }
Kod nr 3 #include <iostream> using namespace std;
int main() { float liczba; bool sprawdzam; cout << "Podaj liczbe: "; cin >> liczba; sprawdzam = cin.good(); if( sprawdzam == false ) { do { cout << "Podaj liczbe: "; cin >> liczba; sprawdzam = cin.good(); cin.clear(); cin.sync(); } while( sprawdzam == false ); } cout << "Twoja liczba to: " << liczba; return 0; }
|
|
carlosmay |
» 2016-07-13 21:50:55 |
|
CCbolt Temat założony przez niniejszego użytkownika |
» 2016-07-14 00:12:39 Czytałem kilka razy ten temat. Dorzuciłem cin.clear();cin.sync(); po wczytaniu pierwszej liczby i działa wszystko jednak dalej nie rozumiem czemu bez tego program się zapętlał w nieskończoność. Program z kodem nr 1 pobiera zapytanie z pętli Do/While i wypisuje je na okrągło, program z kodem nr 3 za pierwszym razem dubluje zapytanie z tej samej pętli Do/While ale tylko za pierwszym razem później pytanie występuje tylko raz.
Rozumiem że bufor jest zapchany błędnymi danymi i trzyma je do czasu ich wyczyszczenia ale w 100% nie rozumiem logiki tego działania. Na pierwszy rzut oka wygląda to tak jakby program wykonywał się do momentu cin >> i zamiast dać mi wpisać dane automatycznie sam sobie je podstawia (mimo że nie powinien) a później wykonuje polecenie jakie zostało napisane, powraca do punktu wyjścia i tak na okrągło.
Kod nr 3 to dla mnie kamikaze, wyświetla 2 pytania obok siebie aby później funkcjonować poprawnie.
Mogę oczywiście schematycznie stosować cin.clear();cin.sync() jednak wolałbym to w pełni zrozumieć. |
|
mateczek |
» 2016-07-14 00:22:41 #include<iostream> #include<limits> using namespace std;
int main() { int liczba; while( !( cin >> liczba ) ) { cin.clear(); cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' ); cout << "to nie liczba" << endl; } cout << "wczytana liczba " << liczba << endl; }
|
|
CCbolt Temat założony przez niniejszego użytkownika |
» 2016-07-14 02:22:36 Próbowałem zacząć od do/while ale coś nie pykło zresztą ( std::numeric_limits < std::streamsize >::max() tego nie znałem. |
|
mateczek |
» 2016-07-14 04:38:55 na linuksie "cin.sync()" nie działa. Trzeba cin.ignore() by opróżnić bufor z niechcianych danych. Zresztą to, że cin.sync() na Windowsie daje rade wyczyścić bufor to chyba jakiś efekt uboczny. PS. Zapoznaj się z instrukcjami break; continue; strasznie ułatwiają sprawę #include<iostream> #include<limits> using namespace std;
int main() { int liczba; while( 1 ) { if( cin >> liczba ) break; cin.clear(); cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' ); cout << "to nie liczba" << endl; } cout << "wczytana liczba " << liczba << endl; } |
|
carlosmay |
» 2016-07-14 05:30:27 PS. Zapoznaj się z instrukcjami break; continue; strasznie ułatwiają sprawę |
Nie całkiem. Lepiej formułować w warunku opuszczanie pętli. Wtedy widać czym pętla się zajmuje. Nadużywając continue i break; zmuszasz się do dogłębniejszej analizy większego fragmentu kodu. Pisz tak, żeby "każdy głupek" mógł zrozumieć. Rozumiem że bufor jest zapchany błędnymi danymi i trzyma je do czasu ich wyczyszczenia ale w 100% nie rozumiem logiki tego działania. |
Po wprowadzeniu błędnych danych strumień ustawia flagę błędu. Póki flagi nie zostaną wyzerowane std::cin.clear(); użycie std::cin będzie zablokowane i pomijane przy każdej próbie wczytywania. Wyzerowanie flag odblokowuje strumień i ponownie możliwe jest pobieranie danych z bufora. Jeśli w bufor nie zostanie oczyszczony ( std::cin.ignore(); ) strumień ponownie zablokuje się na tych samych danych. |
|
CCbolt Temat założony przez niniejszego użytkownika |
» 2016-07-14 05:53:49 @carlosmay Łopatologiczne tłumaczenie jest najlepsze, rozterki rozwiane. Jedno zagadnienie które mnie nurtuje to te z kodu nr3 czyli wystąpienie podwójnego zapytania w jednej linii, dzieje się to tylko raz. Wiem że t błąd i jak go się pozbyć ale z czystej ciekawości się zastanawiam nad tym zjawiskiem, czemu to wygląda tak a nie inaczej. |
|
« 1 » 2 |