while loop stream

0

Witam,

Nie rozumiem pewnej kwestii odnośnie strumieni w C++, a mianowicie:

#include <iostream>

using namespace std;

int ile_testow;
int liczba;
int x=1;
int main()
{
    while(cin>>liczba)
    {
        cout<<liczba<<endl;
    }
    cin>>x; // Czemu to się w ogóle nie wykonuje?
    cout<<x<<endl;
    return 0;
}

Pętla while wykonuje się dopóki zmienna

 liczba 

to faktycznie liczba. Kończę wpisywanie do strumienia np. wklepując na klawiaturze literkę 'V'. Jednak następny cin który ma na celu wczytać zmienną x w ogóle się nie wykonuje. Będę wdzięczny za wytłumaczenie, ewentualnie wskazanie lektury.

0

Wydaje mi się, że powineneś wyczyścić strumień wejściowy

std::cin.clear()

Dzieję sie tak dlatego, że wprowadzając jakiś znak i wciskając enter to do następnego wczytania strumienia wejściowego wchodzi znak \n .
Sorki ale nie wiem jak to napisać :D

1

Tak ale bardziej chodzi o cin.sync() i cin.clear() razem:

#include <iostream>

using namespace std;

int ile_testow;
int liczba;
int x=1;
int main()
{
    while(cin>>liczba)
    {
        cout<<liczba<<endl;
    }
    cin.clear();
    cin.sync();
    cin>>x; // Teraz ta linijka się wykona;
    cout<<x<<endl;
    return 0;
}

Samo cin.clear() nic nie da gdyż tak naprawdę cin.sync() wywala wszystkie śmieci ze strumienia.

1
grzesiek51114 napisał(a):

Samo cin.clear() nic nie da gdyż tak naprawdę cin.sync() wywala wszystkie śmieci ze strumienia.
Bezpieczniej skorzystać zamiast cin.sync z:

cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');

ponieważ funkcjonalność cin.sync, o której piszesz jest zależna od implementacji i nie masz gwarancji, że zawsze zadziała tak jak tego oczekujesz.

0

Krok po kroku, żebyś zrozumiał w czym problem.
Twoja pętla czyt dopóki może wczytywać liczbę.
Gdy natrafi na coś co nie może być zinterpretowane jako liczba int strumień przechodzi w stan błędu, a dane, które wywołały błąd NIE SĄ usuwane ze strumienia.
Wiec jeśli po pętli znowu czytasz, to:

  • strumień jest w stanie błędu, więc nie można odczytać żadnych danych
  • po wyczyszczeniu stanu błędu (clear) w strumieniu nadal jest dostępna dana, która NIE może być zinterpretowana jako int.

cin.sync(); powoduje, że jeśli jest to konsola, to bufor danych jest opróżniany, dopiero jeśli użytkownik coś wpisze nowego to zostanie to wczytane. W przypadku jeśli standardowe wejście nie jest konsolą, zachowanie tej metody nie jest dobrze zdefiniowane.

cin.ignore ignoruje dane aż do napotkania wybranego znaku, więc to co zaproponował matek3005 jest lepszym rozwiązaniem niż sync (w przypadku innym niż konsola program ma szanse dalej kontynuować działanie).

1 użytkowników online, w tym zalogowanych: 0, gości: 1