Проверка с использованием 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;
}