dmx81 Temat założony przez niniejszego użytkownika |
konsolowe problemy (cin i enter) » 2011-01-31 18:46:51 mam menu, przesuwam wskaznik << strzalkami, enterem zatwierdzam MENU -dodaj -usun << -wyswietl wybieram usun i enter,wyswietla mi sie wybierz pozycje do usuniecia: 1. xxx 2. yyy 0 = wyjscie wybieram 0 - czyli wyjscie i enter znow jestem w menu u gory, poruszam wskaznikiem na opcje dodaj. W dodaj w normalnym przypadku wyswietla mi sie pytanie o nazwe, ktora zatwierdzam entrerem i wyskakuje, ze dodano nowy wpis, jednak u mnie ta informacja pojawia sie bez mozliwosci wpisania nazwy kod wyjscia z menu usun while( 1 ) { std::cout << "\n\n Ktora pozycje usunac?\t 0 -> wyjscie z menu usuwania\n\n>"; std::cin >> pos; if( pos == 0 ) { break; } }
void CBox::add() { system( "cls" ); std::cout << "\n\n\nPodaj tytul filmu\n\n>"; std::string title; getline( std::cin, title ); CFilm * ptrFilm = new CFilm( title.c_str() ); vobj.push_back( ptrFilm ); getch(); }
jesli dopisze w menu usun na koncu getch() - nic nie pomaga, jesli napisze getchar, dziala jak nalezy, jesli jednak sprawdzam, czy cos znajduje sie w buforze klawiatury, to nic nie ma, poza tym po wyjsciu z menu usuwania poruszam jeszcze strzalkami, moge wchodzic w inne opcje w miedzy czasie (np wyswietlanie listy dodanych juz filmow, gdzie tez czeka na wyjscie funkcja getch, wiec skasowalaby po drodze to, co siedzi) a tak moge biegac po menu, a wejde w dodaj nowy - od razu informacja, ze obiekt dodano - dopiero po wpisaniu getchar dziala dobrze, ale nie do konca rozumiem, co sie dzieje jesli za bardzo zakrecilem - glowne pytanie brzmi, dlaczego po wprowadzeniu cin >> liczba; w jednej funkcji, automatycznie wykona sie tzn do stringa nie zdarze nic wpisac, mimo ze pomierzy wejsciem do drugiej funkcji bede operowal jeszcze klawiatura (strzalkami), sprawdzanie bufora klawiatury tez nic nie wskazuje, ale dodanie getchar po pierwszej funkcji pomaga |
|
SeaMonster131 |
» 2011-01-31 18:59:37 może musisz dodać "cin.clear()" lub coś podobnego między tymi wpisywaniami? :) |
|
dmx81 Temat założony przez niniejszego użytkownika |
» 2011-01-31 19:03:01 zeby lepiej zobrazowac o co mi chodzi, zalaczam program : programsa 3 wersje, bez niczego, z getch() i getchar() zrobcie tak w menu zejdzcie w dol - na usun - wybierzcie 0 - aby wyjsc znow do menu, po czym wejdzcie w dodaj PS>> no ja wiem, ze mozna zrobic cin.clear() i cin.sync() (u siebie rozwiazalem przez dodanie getchar() jak juz napisalem - i pokazalem w programie), w sumie nie chodzi mi o rozwiazanie problemu a podanie jego przyczyny, dlaczego ten enter sie zapamietuje, mimo ze w miedzy czasie mozna wykonac wiele innych operacji i czy normalnym jest postepowanie, ze przed kazdym wpisywaniem nalezaloby czyscic bufor ( u mnie sprawdzenie kbhit - daje wynik negatywny, tzn jesli uzaleznie getchar od kbhit==true, to sie nie wykona) |
|
malan |
» 2011-01-31 21:11:26 std::cin.clear() nic tutaj nie pomoże, bo flaga błędu i tak jest ustawiona na std::ios_base::goodbit .
(...)dlaczego ten enter sie zapamietuje(...) |
Tak dokładnie mówiąc, to ten znak nowej linii jest w buforze. Mówiąc jeszcze dokładniej, to w buforze znajduje to co nie jest cyfrą.
123lol
W buforze znajduje się lol.
Skompiluj sobie ten programik:
#include <iostream> #include <string>
int main() { int num; std::string str; std::cout << "Podaj liczbe: "; std::cin >> num; if( char( std::cin.peek() ) == '\n' ) std::cout << "BINGO!" << std::endl; std::cout << "Podaj tekst: "; getline( std::cin, str ); std::cout << std::endl; std::cout << "Liczba: " << num << std::endl; std::cout << "Tekst: " << str << std::endl; std::cout << "Aby zakonczyc wcisnij dowolny klawisz..."; std::cin.sync(); std::cin.get(); }
Podaj liczbe: 69
BINGO!
Podaj tekst:
Liczba: 69
Tekst:
Aby zakonczyc wcisnij dowolny klawisz...
Jak widać- w buforze znajduje się znak nowej linii. Domyślny delimiter dla getline to znak nowej linii, więc po wejściu do getline i odczytaniu '\n' z bufora funkcja kończy pracę.
Używając std::cin.sync() czyścisz bufor.
Zróbmy mały test... Ustawmy delimiter na ' ' , czyli: getline( std::cin, str, ' ' );
Podaj liczbe: 123
BINGO!
Podaj tekst: lol
Liczba: 123
Tekst:
lol
Aby zakonczyc wcisnij dowolny klawisz...
Co się dzieje? W buforze znajduje się znak nowej linii, ale nie jest on już znakiem kończącym pracę getline , więc funkcja dopisuje go do stringa (widzisz ten enter po "Tekst:"?) i działa dalej. |
|
dmx81 Temat założony przez niniejszego użytkownika |
» 2011-01-31 22:07:57 dzieki za obszerne wytlumaczenie - takie jak lubie :) teraz rozumiem, co dzieje sie z tym enterem, troszke mnie zmylilo, ze kbhit() zwracalo false, szukalem w zrodlach i znalazlem, ze aby sprawdzic, czy cos znajduje sie w "buforze klawiatury", trzeba sprawdzic kbhit() - no i sprawdzalem, wychodzilo, ze nic - wynika z tego, ze znak nowej linii nie jest widoczny przez kbhit()? mialem cos takiego: int pos; while( 1 ) { cin >> pos; if( pos == 0 ) { if( kbhit() ) { cout << "bufor zajety"; getchar(); } break; } }
PS>> przy okazji - czy dobra praktyka bedzie przed kazdym getline czyscic bufor? ewentualnie przed kazdym wpisywaniem?(ew zmieniac delimiter i sprawdzac czy nie znajduje sie w buforze \n a jesli tak to odrzucac) bo blad ten nie zawsze bedzie zauwazalny od razu... |
|
malan |
» 2011-01-31 23:05:29 czy dobra praktyka bedzie przed kazdym getline czyscic bufor? |
Ja bym proponował po każdym std::cin ;p Co do kbhit() to wszystko odbywa się poprawnie, gdyż funkcja ta sprawdza, czy został wciśnięty klawisz. Fakt, sprawdza bufor klawiatury, aczkolwiek nie odczytuje z niego tego samego co std::cin . Amen. |
|
« 1 » |