在 C++ 中使用 std::cin 将 char 传递给 int
Pass a char to an int in using std::cin in C++
我在要求我接收两个整数并打印它们的练习中遇到问题。但是,当用户输入 '|'
时程序结束。但是,我正在对此进行测试,程序进入无限循环。
问题是什么?
#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;
}
Update:正如@AJNeufeld 指出的 while (i1 != int('|') && i2 != int('|'))
将无法读取 124
,即使输入是整数(等于 ASCII 码垂直管道字符)。
一个可能的解决方案是将两个值都读取为字符串,检查“|
”字符,如果不存在,则将字符串转换为整数,或者报告错误或中断循环。 (感谢@AJNeufeld)
当您使用 >>
从 istream
中提取值时,将从表达式返回原始流。这意味着您可以替换此代码 ...
std::cin >> i1;
std::cin >> i2;
使用此代码:
std::cin >> i1 >> i2;
该表达式的结果再次是原始的 istream
,并且在布尔上下文中使用时,如果流处于“失败”状态,则 returns 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');
}
}
我在要求我接收两个整数并打印它们的练习中遇到问题。但是,当用户输入 '|'
时程序结束。但是,我正在对此进行测试,程序进入无限循环。
问题是什么?
#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;
}
Update:正如@AJNeufeld 指出的 while (i1 != int('|') && i2 != int('|'))
将无法读取 124
,即使输入是整数(等于 ASCII 码垂直管道字符)。
一个可能的解决方案是将两个值都读取为字符串,检查“|
”字符,如果不存在,则将字符串转换为整数,或者报告错误或中断循环。 (感谢@AJNeufeld)
当您使用 >>
从 istream
中提取值时,将从表达式返回原始流。这意味着您可以替换此代码 ...
std::cin >> i1;
std::cin >> i2;
使用此代码:
std::cin >> i1 >> i2;
该表达式的结果再次是原始的 istream
,并且在布尔上下文中使用时,如果流处于“失败”状态,则 returns 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');
}
}