在 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');
    }
}