Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

konsolowe problemy (cin i enter)

Ostatnio zmodyfikowano 2011-01-31 23:05
Autor Wiadomość
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
C/C++
while( 1 )
{
    std::cout << "\n\n Ktora pozycje usunac?\t 0 -> wyjscie z menu usuwania\n\n>";
    std::cin >> pos;
    if( pos == 0 )
    {
        //getchar(); bez tego nie dziala
        // getch(); z tym nie dziala
        break;
    }
}
//dalej kod usuwania jesli inna liczba

//tutaj dodawanie nowej pozycji
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
C/C++
getline( cin, str );

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
P-27595
SeaMonster131
» 2011-01-31 18:59:37
może musisz dodać "cin.clear()" lub coś podobnego między tymi wpisywaniami? :)
P-27596
dmx81
Temat założony przez niniejszego użytkownika
» 2011-01-31 19:03:01
zeby lepiej zobrazowac o co mi chodzi, zalaczam program :

program

sa 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)
P-27598
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ą.
C/C++
int num;
std::cin >> num;
123lol
W buforze znajduje się lol.

Skompiluj sobie ten programik:
C/C++
#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 << std::cin.sync() << 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.
P-27612
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:
C/C++
int pos;
while( 1 )
{
    cin >> pos;
    if( pos == 0 )
    {
        if( kbhit() ) // a jak pominalem ten warunek, to getchar() dzialalo
        {
            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...
P-27616
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.
P-27622
« 1 »
  Strona 1 z 1