为什么这个代码在'|'时会导致无限循环 是用C++输入的?

Dar*_*nas 3 c++ loops cin

我正在阅读编程:使用C++的原理和实践(第2版)
我发现了这个问题:

  • 编写一个由while循环组成的程序(每次循环)读入两个整数然后打印它们.终止'|'时退出程序 进入.

这是我尝试过的:

#include <iostream>
using namespace std;
int main () {
int x, y;
while (x != '|' || y != '|'){
    cin >> x;
    cin >> y;
    cout << x << endl;
    cout << y << endl;
}

return 0;
}
Run Code Online (Sandbox Code Playgroud)

什么时候'|' 输入后,它会输出无限循环,意外输出等内容.

  • 那里发生了什么?
  • 我做错了什么?

pax*_*blo 5

首先,在将它们与循环中进行比较之前,您还没有设置xy任何内容.这意味着它们可能具有任意值,并且您的循环甚至可能无法启动.'|'while


至于为什么你看到一个无限循环,因为变量属于类型int,它cin >> something会尝试将你输入的字符转换成一个整数并将它放入变量中.

如果这些字符的初始序列形成有效整数(例如,它是|字符),cin >>则将失败,变量将保持不变,输入流将保持原样.

所以,当你再来各地去下一个整数,|仍然在输入流中和同样的事情会再次发生,循环往复-注意,拉丁短语和你的问题的标题之间的相似性:-)


你可以做些什么来解决这个问题,试图逐个字符地查看你是否|在流中有一个.如果是这样,请退出.如果没有,尝试使用常规if (stream >> variable)方法获得两个整数.

这可以通过cin.peek()检查下一个字符和cin.get()删除字符来完成.你还必须考虑到这样一个事实:既peek不会也get不会以operator>>可能的方式跳过空格.

这样的事情应该是一个好的开始:

#include <iostream>
#include <cctype>

int main() {
    int x, y;

    while (true) {
        // Skip all white space to (hopefully) get to number or '|'.

        while (std::isspace(std::cin.peek())) std::cin.get();

        // If it's '|', just exit, your input is done.

        if (std::cin.peek() == '|') break;

        // Otherwise, try to get two integers, fail and stop if no good.

        if (! (std::cin >> x >> y)) {
            std::cout << "Invalid input, not two integers\n";
            break;
        }

        // Print the integers and carry on.

        std::cout << "You entered " << x << " and " << y << "\n";
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用各种测试数据表明它涵盖了所有情况(我能想到的):

pax$ ./myprog </dev/null
Invalid input, not two integers

pax$ echo hello | ./myprog
Invalid input, not two integers

pax$ echo 1 | ./myprog
Invalid input, not two integers

pax$ echo 1 2 | ./myprog
You entered 1 and 2
Invalid input, not two integers

pax$ printf '1 2|' | ./myprog
You entered 1 and 2

pax$ printf '1 2\n3 4\n5     6 7   8   \n|' | ./myprog
You entered 1 and 2
You entered 3 and 4
You entered 5 and 6
You entered 7 and 8

pax$ printf '1 10     11   12   13    14    |   ' | ./myprog
You entered 1 and 10
You entered 11 and 12
You entered 13 and 14
Run Code Online (Sandbox Code Playgroud)