Działa, tylko nie robi tego, czego oczekujesz
To jest typowy kod, który sprawia problemy:
#include <iostream>
#include <string>
int main()
{
int liczba;
std::string tekst;
std::cout << "Podaj liczbe: ";
std::cin >> liczba;
std::cout << "Podaj tekst: ";
std::getline( std::cin, tekst );
std::cout << "liczba = " << liczba << "; tekst = \"" << tekst << "\"\n";
}
Program pyta o liczbę, podajemy przykładowo 5
Podaj liczbe: 5
Podaj tekst: liczba = 5; tekst = ""
I wczytało 5, ale
std::getline() 'nie zadziałało' i wczytało pusty łańcuch, bez zatrzymania programu w oczekiwaniu na dane. A to dlatego, że
std::getline() miało już dane do odczytania. Podajmy dane wejściowe inaczej:
Podaj liczbe: 5ala ma kota
Podaj tekst: liczba = 5; tekst = "ala ma kota"
Wciąż się program nie zatrzymał na podawaniu tekstu przez użytkownika, ale jak widać tekst został wczytany poprawnie. Problem jest w tym, jak te dwie metody są użyte razem. Wczytywanie operatorem >> wczytuje do białego znaku (lub błędnego znaku), w tym przypadku do znaku nowej linii, ale
zostawia ten znak w strumieniu. Następne użycia tego operatora ignorują białe znaki poprzedzające dane.
std::getline() wczytuje jak leci, aż dojdzie do końca pliku, lub ustawionego znaku kończącego - domyślnie znaku nowej linii. Nie dołącza znaku kończącego do wczytanych danych, ale
usuwa go ze strumienia.
Dlatego jeśli
std::getline() jest użyte po
>>, funkcja może się zakończyć natychmiastowo, poprzez zostawiony znak nowej linii. Rozwiązanie to usunąć resztę linii, wraz ze znakiem nowej linii, ze strumienia.
#include <iostream>
#include <string>
#include <limits>
int main()
{
int liczba;
std::string tekst;
std::cout << "Podaj liczbe: ";
std::cin >> liczba;
std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
std::cout << "Podaj tekst: ";
std::getline( std::cin, tekst );
std::cout << "liczba = " << liczba << "; tekst = \"" << tekst << "\"\n";
}
Podaj liczbe: 5
Podaj tekst: ala ma kota
liczba = 5; tekst = "ala ma kota"
Podaj liczbe: 123 wszystko dalej zostanie pominiete
Podaj tekst: zostanie wczytane tylko to
liczba = 123; tekst = "zostanie wczytane tylko to"