在C++中使用 std::cin 将字符传递给 int

Pass a char to an int in using std::cin in C++

本文关键字:字符 int cin std C++      更新时间:2023-10-16

我在练习中遇到问题,该练习要求我接收两个整数并打印它们。但是,当用户以条目'|'输入时,程序结束。但是,我正在对此进行测试,程序进入无限循环。 问题出在哪里?

#include <iostream>
using namespace std;
int main ()
{
int i1 = 0, i2 = 0;
cin >> i1;
cin >> i2;
while (i1 != int('|') && i2 != int('|'))
{
cout << i1 << endl;
cout << i2 << endl;
cin >> i1 >> i2; 
} 
return 0;
}

当您在循环中std::cin非整数类型(字符 '|'(时,它会失败。使用std::cin.fail()检查。

例如,运行以下命令,您将了解发生这种情况的原因:

while (i1 != int('|') && i2 != int('|'))
{
std::cout << i1 << endl;
std::cout << i2 << endl;
std::cin >> i1 ;  // std::cin fails here, in the the case of '|'
if(std::cin.fail()) { std::cout << "Failed"; break;}
std::cin >> i2;  // std::cin fails here, in the the case of '|'
if(std::cin.fail()) { std::cout << "Failed"; break;}
}

上面将修复代码。但是,您也可以通过检查std::cin::fail()来为任何std::cin失败的情况编写代码。

while ( std::cin >> i1 && !std::cin.fail()   // check wether i1 failed, if not continue
&& std::cin >> i2 && !std::cin.fail() ) // check wether i2 failed, if not continue
{
std::cout << i1 << "n" << i2 << std::endl;
}

更新:正如@AJNeufeld指出的那样while (i1 != int('|') && i2 != int('|'))将无法读取124,即使输入也是整数(等于垂直管道字符的 ASCII 码(。

一个可能的解决方案是将两个值都读取为字符串,检查"|"字符,如果不存在,将字符串转换为整数,或报告错误或中断循环。(致@AJNeufeld

(

当您使用>>istream中提取值时,原始流将从表达式返回。 这意味着您可以替换此代码...

std::cin >> i1;
std::cin >> i2;

使用此代码:

std::cin >> i1 >> i2;

该表达式的结果再次是原始istream,并且在布尔上下文中使用时,如果流处于"失败"状态,则返回false。 因此,我们可以读取两个整数,并在一个简单的构造中测试它是否成功:

if( std::cin >> i1 >> i2 ) {
std::cout << i1 << "n" << i2 << "n";
} else {

上面的流将进入失败状态,当它尝试读取整数并遇到非整数字符(例如垂直管道(时。 为了测试这一点,我们需要首先清除错误状态,然后查看流中导致整数读取失败的字符。 我们可以通过偷看下一个角色是什么来做到这一点。

} else {
std::cin.clear();    // reset the fail state
if (std::cin.peek() == '|') {
std::cout << "Found end of input marker (|)n";
} else {
std::cout << "Invalid input!";
}

确定它是否是垂直管道后,明智的做法是清除流中的所有字符,直到输入行的末尾。

// skip all characters in the stream up to the end of the current line.
std::cin.ignore(std::numeric_limits<streamsize>::max(), 'n');
}

将上面的代码放在一个循环中,找到垂直管道时添加一个break语句,您将循环,成对读取整数值,直到您输入|.

while ( !std::cin.eof() ) {
if( std::cin >> i1 >> i2 ) {
std::cout << i1 << "n" << i2 << "n";
} else {
std::cin.clear();    // reset the fail state
if (std::cin.peek() == '|') {
std::cout << "Found end of input marker (|)n";
break;
} else {
std::cout << "Invalid input!";
}
// skip all characters in the stream up to the end of the current line.
std::cin.ignore(std::numeric_limits<streamsize>::max(), 'n');
}
}