Totalq Temat założony przez niniejszego użytkownika |
Lekcja 26 - problem z zabezpieczeniem » 2012-12-04 21:50:25
#include <iostream> #include <string>
void wczytajOsobe( std::string & imie, std::string & nazwisko, int & wiek ) { bool x; std::cout << "Podaj imie: "; std::cin >> imie; std::cout << "Podaj nazwisko: "; std::cin >> nazwisko; std::cout << "Podaj wiek: "; std::cin >> wiek; x = std::cin.fail(); if( x == true ) do { std::cin.sync(); std::cin.clear(); std::cout << "Blad, wpisz wiek ponownie: "; std::cin >> wiek; x == std::cin.fail(); } while( x == true ); }
void wypiszOsobe( std::string imie, std::string nazwisko, int wiek ) { std::cout << "Imie: " << imie; std::cout << std::endl << "Nazwisko: " << nazwisko; std::cout << std::endl << "Wiek: " << wiek << std::endl; }
int main() { std::string imie[ 2 ]; std::string nazwisko[ 2 ]; int wiek[ 2 ]; for( int i = 0; i < 2; i++ ) wczytajOsobe( imie[ i ], nazwisko[ i ], wiek[ i ] ); std::cout << std::endl; for( int i = 0; i < 2; i++ ) wypiszOsobe( imie[ i ], nazwisko[ i ], wiek[ i ] ); return 0; }
Co bym nie wymyślił to przy próbie wpisania czegoś dziwnego w ,,wieku" program crashuje, zamiast pozwolić mi ponownie wpisać wartość. Pomożecie? ;) |
|
Mrovqa |
» 2012-12-04 21:58:57 Nie myl operatorów przypisania i porównania. |
|
Totalq Temat założony przez niniejszego użytkownika |
» 2012-12-05 20:07:55 Po poprawieniu fukcji wczytajOsobe() void wczytajOsobe( std::string & imie, std::string & nazwisko, int & wiek ) { bool x; std::cin.sync(); std::cout << "Podaj imie: "; std::cin >> imie; std::cout << "Podaj nazwisko: "; std::cin >> nazwisko; std::cout << "Podaj wiek: "; std::cin >> wiek; x = std::cin.fail(); if( x == 1 ) do { std::cin.sync(); std::cin.clear(); std::cout << "Blad, wpisz wiek ponownie: "; std::cin >> wiek; x = std::cin.fail(); } while( x == 1 );
Program dalej nie działa prawidłowo przy wpisaniu np. litery do wieku. ***EDIT*** Uff, rozgryzłem, jednakże zrodziło się pewne pytanie. Działający kod: void wczytajOsobe( std::string & imie, std::string & nazwisko, int & wiek ) { bool x; std::cin.sync(); std::cout << "Podaj imie: "; std::getline( std::cin, imie ); std::cout << "Podaj nazwisko: "; std::getline( std::cin, nazwisko ); std::cout << "Podaj wiek: "; std::cin.sync(); std::cin >> wiek; x = std::cin.fail(); if( x == 1 ) do { std::cout << "Blad, wpisz ponownie: "; std::cin.clear(); std::cin.sync(); std::cin >> wiek; x = std::cin.fail(); } while( x == 1 ); }
Jak dotąd nie wiedziałem, że jest jakaś różnica, czy napiszemy tak: std::cin.clear(); std::cin.sync(); czy tak: std::cin.sync(); std::cin.clear(); Mógłby mi ktoś jeszcze raz dokładniej wytłumaczyć dlaczego kolejność jest ważna i co dokładnie wykonują te metody(?). |
|
f0g |
» 2012-12-05 20:48:27 u mnie powyższy kod działa poprawnie(gdy wpisze literę jako wiek prosi o poprawny wiek) std::cin.clear() czyści flagi błędu, a std::cin.sync() czyści bufor strumienia. |
|
Totalq Temat założony przez niniejszego użytkownika |
» 2012-12-07 20:56:20 Nie wiele mi to pomogło. Dalej nie wiem dlaczego ważne jest zachowanie kolejności. Prosiłbym też o dokładniejsze objaśnienie terminu ,,czyści flagi błędu" jeśli chodzi o metodę cin.clear(); |
|
mszumny |
» 2016-03-01 17:21:52 #include <iostream> #include <string>
using namespace std; void wczytajOsobe(string & imie , string & nazwisko , int & wiek) { bool x1, x2, x3; cout << "Podaj imie: "; cin >> imie; x1 = cin.good();
cout << "Podaj nazwisko: "; cin >> nazwisko; x2 = cin.good();
cout << "Podaj wiek: "; cin >> wiek; x3 = cin.good(); if (x1,x2,x3 == false ) do { cin.clear(); cin.sync(); cout << "Blad, wypisz ponownie , imie, nazwisko, wiek: ";
cin >> imie >> nazwisko >> wiek; x1,x2,x3 = cin.good();
} while (x1,x2,x3 == false);
} void wypiszOsobe (string imie , string nazwisko , int wiek) { cout << imie << endl; cout << nazwisko << endl; cout << wiek<< endl; }
int main() { string imie[ 2 ]; string nazwisko[ 2 ]; int wiek[ 2 ]; for( int i = 0; i < 2; i++ ) wczytajOsobe( imie[ i ], nazwisko[ i ], wiek[ i ] );
for( int i = 0; i < 2; i++ ) wypiszOsobe( imie[ i ], nazwisko[ i ], wiek[ i ] );
return 0; } |
|
carlosmay |
» 2016-03-01 20:26:25 Dalej nie wiem dlaczego ważne jest zachowanie kolejności. |
Błąd wczytania danych ze strumienia do zmiennej powoduje ustawinie się strumienia w stan błędu. To blokuje działanie na obiekcie std::cin . Nic nie można zrobić póki nie zresetujemy flagi błędu metoda std::cin.clear() , czyli std::cin.sync() próbuje wyczyścić zablokowany strumień. Swoją drogą to std::cin.ignore() służy do czyszczenia strumienia. |
|
« 1 » |