我要求用户输入一个整数,除非严格为整数,否则不执行代码。
int x;
if(cin >> x)
例如,如果用户输入一个double类型的值,if语句将会使用隐式转换成为整型来执行。但是我不想让代码执行。
我该如何防止这种情况发生?
我要求用户输入一个整数,除非严格为整数,否则不执行代码。
int x;
if(cin >> x)
这里没有转换。如果用户输入的是分数(不是 double
),那么 >>
提取会在小数点处停止。
int main() {
int x;
std::cin >> x;
std::cout << std::cin.rdbuf();
}
input:
123.456
output:
.456
如果你想将十进制小数点的存在视为错误,你需要做一些操作来从cin
中提取它并进行检测。getline
提取到一个istringstream
中,命名为s
,然后在完成时检查s.peek() == std::char_traits<char>::eof()
。如果您不使用getline
来提取单个数字,则peek
可以检查下一个字符是否为空格(使用std::isspace
),而不会将该字符从流中消耗掉。std::istream::sentry
。if ( ! ( std::cin >> x ) || std::istream::sentry( std::cin ) ) {
std::cerr << "Invalid or excessive input.\n";
}
这会消耗输入末尾的空格。 sentry
还提供了一个 noskipws
选项来避免消耗空格。
if ( ! ( std::cin >> x ) || std::istream::sentry( std::cin, true ) ) {
std::cerr << "Invalid or excessive input. (No space allowed at end!)\n";
}
rdbuf()
是否包含额外的非空格内容(默认情况下为空将是可以接受的)是一个绝妙的解决方法。+1 - WhozCraig这似乎有效。它忽略空格,我不知道你是否满意。
string s;
cin >> s;
stringstream ss(s);
int x;
if (! (ss >> x))
{
cerr << "You didn't enter an integer." << endl;
return -1;
}
string temp;
ss >> temp;
if (! temp.empty())
{
cerr << "You didn't enter an integer." << endl;
return -1;
}
if (! (ss >> x) || ss.peek() != stringstream::traits::eof() )
,可以实现我的建议,并且更加DRY。 - Potatoswatter||
按顺序处理其操作数。左侧的所有副作用在右侧开始之前已经完成。除非它被重载了,否则这只会是一种恶劣的做法。(但这里不可能适用于重载。) - Potatoswatterstd::string
提取器初始化的。另一种不需要虚拟临时变量并允许空格的策略是|| std::istream::sentry( ss )
。这可能更清晰,因为你还可以传递(ss, true)
来不容忍空格。 - Potatoswatter
<<
为你做的事情,对吧?你想要更多的控制……那就自己动手吧。 - Steven Lu