Во время сбоя цикла, при чтении int и строки C ++ - PullRequest
1 голос
/ 28 февраля 2012

Я пытаюсь прочитать несколько Strings и ints от пользователя. Я хочу взять пары Name и Age и продолжать делать это, пока пользователь не введет «done». Но мой do-while рано падает, и я не могу понять, почему?

int number;
string name;
do
{
cout << "Your name: " ;
getline(cin, name);    
cout <<name<< " age: " ;
cin >> number;
}
 while (name!="done");

Редактировать: Также после ввода "готово", я должен ввести "готово" также по возрасту, почему это так?

Ответы [ 5 ]

2 голосов
/ 28 февраля 2012

Я пытался запустить вашу программу в VS 2010, и даже когда я ввел правильный номер, программа, к моему удивлению, пропустила чтение следующего имени.

Мне кажется, что cin >> number не'' проглотить '\ n', который я, естественно, ввел после числа.

Я попытался добавить вызов getchar () после каждого cin >> number, и программа неожиданно начала работать, как и ожидалось.

Таким образом, вывод заключается в том, что вы должны очистить () / ignore () после cin >> number даже после того, как введенное число было в порядке, или прибегнуть к использованию getline () (и затем синтаксического анализа) для чтения чисел.

Еслиесли вы не хотите вводить возраст «готово», то вы должны выйти из цикла сразу после его ввода.Мой окончательный код:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    int number;
    string name;
    while(true)
    {
        cout << "Your name: " ;
        getline(cin, name);
        if(name == "done") 
            break;
        cout <<name<< " age: " ;
        cin >> number;
        cin.clear();
        cin.ignore(std::numeric_limits<streamsize>::max(),'\n');
    }
}
2 голосов
/ 28 февраля 2012

Если кто-то вводит недопустимый возраст, то есть что-то, что не является числом, вам нужно очистить флаги вашего cin, а также сбросить все оставшиеся символы.

if( !(cin >> number )
{
     cin.clear();
}
cin.ignore( std::numeric_limits<streamsize>::max() );

Если он читает число, вам также нужно игнорировать символ новой строки после него.

1 голос
/ 28 февраля 2012

Использовать пространство имен std

Так

int number;
string name;
do
{
std::cout<<"Your name: " ;
std::cin>>name;    
std::cout<<name<<" age: " ;
std::cin>>number;
}
while (name!="done");

Или это

using namspace std;
int number;
    string name;
    do
    {
    std::cout<<"Your name: " ;
    std::cin>>name;    
    std::cout<<name<<" age: " ;
    std::cin>>number;
    }
    while (name!="done");
1 голос
/ 28 февраля 2012
#include <iostream>
#include <string>

int main ()
{
    std::string name;
    int age;
    while (true)
    {
        std::cout << "Please enter your name: ";
        std::cin >> name;
        if ( "done" == name )
            break;
        std::cout << name << ", please enter your age: ";
        std::cin >> age;
        std::cout << name << ", you are " << age << " years old\n";
    }
    std::cout << "Bye.\n";
    return 0;
}

Смешанное использование getline() и >> может быть проблематичным. Лучше всего избегать этого, если можете. Вы также можете использовать getline() для обоих, и конвертировать int, используя stringstream или, возможно, atoi(), но мне это не очень нравится.

0 голосов
/ 28 февраля 2012

Поскольку вы даете ей строку , в то время как она ожидает int как age.

В конце первой итерации, когда вы набираете Введите , чтобы ввести age, дополнительная новая строка была взята в cin.Таким образом, во второй итерации символ новой строки был показан как пустая строка, в результате чего name был установлен как пустая строка.Тогда программа хотела int как age.Если вы недостаточно осторожны, вы должны ввести строку и вызвать сбой программы.

Одно предложение: заменить:

getline(cin, name);  

на:

do {
    getline(cin, name);    
} while (name.empty());
...