2011-07-10 17 views
5

To prawdopodobnie bardzo prosty problem, ale wybacz mi, że jestem nowy. Oto mój kod:getline nie pyta o wejście?

#include <iostream> 
#include <string> 
#include <sstream> 
using namespace std; 

int main() 
{ 
    string name; 
    int i; 
    string mystr; 
    float price = 0; 

    cout << "Hello World!" << endl; 
    cout << "What is your name? "; 
    cin >> name; 
    cout << "Hello " << name << endl; 
    cout << "How old are you? "; 
    cin >> i; 
    cout << "Wow " << i << endl; 

    cout << "How much is that jacket? "; 
    getline (cin,mystr); 
    stringstream(mystr) >> price; 
    cout << price << endl; 
    system("pause"); 

    return 0; 
} 

Problemem jest to, że pytany how much is that jacket? getline nie prosi użytkownika o wejściu i po prostu wejść początkową wartość „0”. Dlaczego to?

+1

Uwaga: Zostało to zadane wiele razy. Oto kilka http://stackoverflow.com/questions/3731529/program-is-skipping-over-getline- without-taking-user-input http://stackoverflow.com/questions/1744665/need-help- with-getline http://stackoverflow.com/questions/4876959/ignore-spaces-using-getline-in-c – cpx

Odpowiedz

12

Trzeba być ostrożnym podczas mieszania operator>> z getline. Problem polega na tym, że kiedy używasz operator>>, użytkownik wprowadza swoje dane, a następnie naciska klawisz Enter, który wstawia znak nowego wiersza do bufora wejściowego. Ponieważ operator>> jest rozdzielane białymi znakami, znak nowego wiersza nie jest wprowadzany do zmiennej i pozostaje w buforze wejściowym. Następnie, wywołując getline, jedyną rzeczą, której szuka, jest znak nowej linii. Ponieważ jest to pierwsza rzecz w buforze, od razu znajduje to, czego szuka i nigdy nie musi monitować użytkownika.

Fix: Jeśli masz zamiar zadzwonić getline po użyciu operator>>, zadzwoń ignorować pomiędzy, lub zrobić coś innego aby pozbyć się tego znaku nowej linii, być może manekina wywołaniu getline.

Inną opcją, która jest podobna do tego, o czym mówił Martin, jest nieużywanie w ogóle operator>> i używanie tylko getline, a następnie konwertowanie ciągów do dowolnego typu danych, którego potrzebujesz. Ma to skutek uboczny, że Twój kod będzie bezpieczniejszy i bardziej wytrzymały. Najpierw napiszę taką funkcję:

int getInt(std::istream & is) 
{ 
    std::string input; 
    std::getline(is,input); 

    // C++11 version 
    return stoi(input); // throws on failure 

    // C++98 version 
    /* 
    std::istringstream iss(input); 
    int i; 
    if (!(iss >> i)) { 
     // handle error somehow 
    } 
    return i; 
    */ 
} 

Możesz stworzyć podobną funkcję dla pływających, podwójnych i innych rzeczy. Wtedy, gdy trzeba w int, zamiast tego:

cin >> i; 

to zrobić:

i = getInt(cin); 
+0

Dziękuję bardzo Benjamin!Rozumiem Cię całkowicie – UzumakiDev

+0

Dlaczego nie dołączyłem do tej strony wcześniej: -/ – UzumakiDev

+0

Czy "return stoi (input)" w zasadzie oznacza, że ​​jeśli typem zwracanym jest ciąg, przekonwertuj na liczbę całkowitą? – UzumakiDev

2

To dlatego, że masz '\n' pozostawiony na strumieniu wejściowym z poprzedniego połączenia.

cin >> i; // This reads the number but the '\n' you hit after the number 
      // is still on the input. 

Najłatwiej zrobić interaktywną wprowadzania danych przez użytkownika jest upewnienie się, każda linia jest przetwarzany niezależnie (jako użytkownik naciśnij enter po każdym szybka).

W rezultacie zawsze czytaj wiersz, a następnie przetwarzaj linię (dopóki nie zapoznasz się ze strumieniami).

std::string line; 
std::getline(std::cin, line); 

std::stringstream linestream(line); 

// Now processes linestream. 
std::string garbage; 
lienstream >> i >> garbage; // You may want to check for garbage after the number. 

if (!garbage.empty()) 
{ 
    std::cout << "Error\n"; 
} 
+0

Nie rozumiem? Co dokładnie sugerujesz, aby uzyskać getline, aby poprosić o wejście? Przepraszam, jestem kompletny n00b – UzumakiDev

+0

Dziękuję wam, obydwoje, będę o tym pamiętał, gdy tylko zrozumiem, co robię, trochę więcej .. Pozdrawiam – UzumakiDev

+0

Znalazłem to bardzo przydatne [link] http://augustcouncil.com/ ~ tgibson/tutorial/iotips.html [link] – UzumakiDev

2

ignorowanie niektórych znaków, aż do osiągnięcia nowego wiersza.

cin.ignore(256, '\n') 
getline (cin,mystr); 
+0

Czy możesz wyjaśnić to trochę więcej? Dlaczego ignorowanie 256 znaków nie jest czymś więcej niż bajtem, więc dlaczego 256? – UzumakiDev

+0

Jest to _maksymalna liczba znaków do wyodrębnienia lub zignorowania ze strumienia wejściowego. Możesz mieć liczbę większą niż 256 w zależności od długości twojego wejścia. W twoim przypadku założyłem, że 256 jest maksymalną długością znaków wejściowych dla ciągu 'name'. – cpx