检查空的sstream

Check for Empty sstream

本文关键字:sstream 检查      更新时间:2023-10-16

我编写了一个函数,该函数可以替换整数和可能加倍的cin,其中包括错误检查功能。使用cin.fail(),我可以检查大多数情况,但这还不包括输入后面跟着一个没有空格的字符串的情况。例如,"23tewnty three"。下面的代码包含了这一点。

int getUserInt(string prompt = "Enter an integer: ", string errorMessage "Error: Invalid Input") {
const int IGNORE_MAX = 100;
int userInt = 0;
bool isContinue = true;
do {
// initialize and reset variables
string inputStr;
istringstream inputCheck;
userInt = 0;
// get input
cout << prompt;
cin >> inputStr;
inputCheck.str(inputStr);
// check for valid input
inputCheck >> userInt;
if (!inputCheck.fail()) {
// check for remaining characters
if (inputCheck.eof()) {    // Edit: This is the section that I tried replacing with different code (made code compilable in response to comment)
isContinue = false;
}
else {
cout << errorMessage << endl;
}
}
else {
// reset cin and print error message
cin.ignore(IGNORE_MAX, 'n');
cin.clear();
cout << errorMessage << endl;
}
} while (isContinue);
return userInt;
}

这段代码是有效的,但我之所以把它发布到Stack Overflow而不是code Review,是因为我的主要问题是为什么有些代码没有像我预期的那样工作。以下是我在前一段代码中尝试的inputCheck.eof()。我的问题是以下代码之间有什么区别?为什么方法2)和3)不起作用?首选哪种方法?

  1. inputCheck.eof()
  2. inputCheck.peek() == EOF
  3. inputCheck.str().empty()
  4. inputCheck.rdbuf()->in_avail() == 0

1)和4)按预期工作,但2)和3)没有。

编辑:我认为3)没有按预期工作,因为inputCheck.str()在调用inputCheck.str(inputStr)时返回inputStr中包含的内容。然而,我不知道inputCheck.peek() == EOF为什么不起作用。

如果这是相关信息,我将通过bash g++在windows上编译和运行。

对于您提供的每个提示,您可以期望用户按Enter键。获取字符串形式的输入,然后尝试转换。(不要尝试从cin转换。)

额外奖励:这里有一个执行转换的功能。

template <typename T>
auto string_to( const std::string & s )
{
T value;
std::istringstream ss( s );
return ((ss >> value) and (ss >> std::ws).eof())
? value
: std::optional<T> { };
}

为此,您需要C++17,或者使用#include <boost/optional.hpp>

现在:

std::cout << "Enter an integer! ";
std::string s;
getline( std::cin, s );
auto x = string_to <int> ( s );
if (!x)
{
std::cout << "That was _not_ an integer.n";
}
else
{
std::cout << "Good job. You entered the integer " << *x << ".n";
}

不再担心清除或重置cin。方便地执行一些循环(例如允许用户在退出前尝试三次)。等等。