Проверка с использованием sstream не удалась

cout << "\nPlease enter x-ordinate: ";

cin >> test;
stringstream ss(test);
ss >> x;
while(ss.fail())
{
ss.str("");
cin.clear();
cin.ignore(256, '\n');  
cout << "Please enter integer: \n";
cin >> test;
stringstream ss(test);
ss >> x;
cout << x << ss;    
}       

Привет, я пытаюсь проверить, является ли ввод пользователя целым числом или нет, используя sstream, чтобы проверить, можно ли его преобразовать в целое число x, но как только я ввожу правильное целое число, циклы while все еще подтверждаются и цикл продолжается. Может ли кто-нибудь помочь?

3 ответа

Решение

Там нет смысла потокового из cin в string, создавая istringstream, а затем стриминг оттуда на ваш номер: он просто оставляет место для дополнительных типов ошибок, таких как "12x" рассматривается как 12 и x игнорируется вместо того, чтобы выдавать предупреждение / сообщение об ошибке для пользователя.

Вы можете прочитать более прямо следующим образом:

const char* prompt = "\nPlease enter x-coordinate: ";
while (cout << prompt && !(cin >> x))
{
    cin.clear();
    cin.ignore(256, '\n');  
    prompt = "Please enter integer: \n";
}

Если вам не нужно менять подсказку, вы можете поместить ее прямо в цикл:

while (cout << "\nPlease enter x-coordinate: " && !(cin >> x))
{
    cin.clear();
    cin.ignore(256, '\n');  
    std::out << "Please enter an integer.\n";
}

Примечание: вы увидите что-то похожее на ваши первые усилия, где чтение к string использования getline скорее, чем >>и это может быть хорошей практикой, поскольку позволяет подсчитывать номера строк (более полезно для разбора файлов, чем std::cin) и контрольные значения появляются в строках вместе с другими ожидаемыми данными. Это выглядит так:

std::string line;
while (std::cout << "Enter coordinate:" &&
       getline(std::cin, line))
{
    std::istringstream iss(line);
    if (iss >> x)
         break;
    std::cout << "Error - invalid coordinate, please enter an integer\n";
}
...use x...

Есть небольшая проблема с кодом, который у вас есть... у вас есть две совершенно разные переменные с одним и тем же именем, одна используется в условии цикла, одна находится внутри тела цикла. Эти две переменные никак не связаны или связаны между собой.

Вместо этого используйте первый ss переменная, установив ее строку:

...
cin >> test;
ss.str(test);
...

Вы также не очищаете статус ss поток в цикле, только из cinВот почему ваш цикл никогда не заканчивается.

Я бы также предложил вам использовать тот факт, что поток может быть использован как логическое условие, и что operator>> функция возвращает ссылку на поток, тогда вы можете сделать что-то вроде

cout << "\nPlease enter x-ordinate: ";
getline(cin, test);

istringstream ss(test);
while(!(ss >> x))
{
    ss.clear();
    cout << "Please enter integer: \n";
    getline(cin, test);
    ss.str(test);
}

Смотрите здесь для примера выше.


Конечно, можно использовать cin также напрямую:

int x;
while (!(cin >> x))
{
    cin.clear();
    cin.ignore(numeric_limits<std::streamsize>::max(), '\n');
    cout << "Please enter integer: \n";
}

Смотрите здесь для примера выше.

Какой тип тестовой переменной? строка? Вы можете попробовать этот общий синтаксический анализатор, взяв строку в качестве входных данных:

template<class T>
bool tryparse(const string word, T& res)
{
   istringstream parser(word);
   bool status = (parser >> res);
   return status;
}
Другие вопросы по тегам