为什么此代码在“|”时会导致无限循环在C++中输入?
Why this code cause an infinity loop when '|' is entered in C++?
我正在阅读编程:使用 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;
}
当'|'输入时,它会打印类似无限循环的内容,意外的输出。
- 那里发生了什么?
- 我做错了什么?
首先,在将 x
或 y
与 while
循环中的 '|'
进行比较之前,您没有设置任何值。这意味着它们可能具有 任意 值,您的循环甚至可能无法启动。
至于为什么你会看到一个无限循环,因为变量的类型是int
,cin >> something
会尝试翻译字符您输入 到 一个整数并将其放入变量。
如果这些字符的初始序列 不是 形成有效整数(例如,它是 |
字符),则 cin >>
将失败,变量将保持不变,输入流将保持原样。
因此,当您再次获得下一个整数时,|
在输入流中仍然是 ,完全相同的事情将再次发生,无穷无尽- 请注意该拉丁短语与您的问题标题之间的相似性:-)
要解决这个问题,您可以 尝试 逐个字符地向前看,看看流中是否有 |
。如果是这样,请退出。如果不是,请尝试使用正常的 if (stream >> variable)
方法获取两个整数。
这可以用 cin.peek()
来检查下一个字符,用 cin.get()
来删除一个字符。您还必须考虑到 peek
和 get
都不会像 operator>>
那样跳过白色 space。
这样的事情应该是一个好的开始:
#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;
}
使用各种测试数据表明它涵盖了所有情况(我能想到的):
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
因为您将 x 和 y 定义为整数,但您输入的是字符形式。
试试这个代码
#include <iostream>
using namespace std;
int main ()
{
char x=NULL, y=NULL;
while (x != '|' || y != '|')
{
cin >> x;
cin >> y;
cout << x << endl;
cout << y << endl;
}
return 0;
}
但它也有局限性。你只能接受单个输入 digit.if 你想输入大数字试试这个
#include <iostream>
using namespace std;
int main ()
{
string x="", y="";
while (x != "|" || y != "|")
{
cin >> x;
cin >> y;
cout << x << endl;
cout << y << endl;
}
return 0;
}
正如人们在评论和 paxdiablo 的回答中指出的那样,您有两个未初始化的变量,您正在尝试输入一个 int,然后将其与 char 进行比较。
我们可以使用 cin.peek()
查看下一个字符并检查它是否为“|”,而不是尝试将输入的 int 与 char 进行比较在阅读之前。
#include <iostream>
int main()
{
int x, y;
while(std::cin.peek() != '|') //cin.peek() will return the next character to be read
{
std::cin >> x >> y;
std::cout << x << ' ' << y << '\n';
std::cin.ignore(); //ignore whitespace/linebreak character left by extraction (>> operator)
}
}
我正在阅读编程:使用 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;
}
当'|'输入时,它会打印类似无限循环的内容,意外的输出。
- 那里发生了什么?
- 我做错了什么?
首先,在将 x
或 y
与 while
循环中的 '|'
进行比较之前,您没有设置任何值。这意味着它们可能具有 任意 值,您的循环甚至可能无法启动。
至于为什么你会看到一个无限循环,因为变量的类型是int
,cin >> something
会尝试翻译字符您输入 到 一个整数并将其放入变量。
如果这些字符的初始序列 不是 形成有效整数(例如,它是 |
字符),则 cin >>
将失败,变量将保持不变,输入流将保持原样。
因此,当您再次获得下一个整数时,|
在输入流中仍然是 ,完全相同的事情将再次发生,无穷无尽- 请注意该拉丁短语与您的问题标题之间的相似性:-)
要解决这个问题,您可以 尝试 逐个字符地向前看,看看流中是否有 |
。如果是这样,请退出。如果不是,请尝试使用正常的 if (stream >> variable)
方法获取两个整数。
这可以用 cin.peek()
来检查下一个字符,用 cin.get()
来删除一个字符。您还必须考虑到 peek
和 get
都不会像 operator>>
那样跳过白色 space。
这样的事情应该是一个好的开始:
#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;
}
使用各种测试数据表明它涵盖了所有情况(我能想到的):
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
因为您将 x 和 y 定义为整数,但您输入的是字符形式。 试试这个代码
#include <iostream>
using namespace std;
int main ()
{
char x=NULL, y=NULL;
while (x != '|' || y != '|')
{
cin >> x;
cin >> y;
cout << x << endl;
cout << y << endl;
}
return 0;
}
但它也有局限性。你只能接受单个输入 digit.if 你想输入大数字试试这个
#include <iostream>
using namespace std;
int main ()
{
string x="", y="";
while (x != "|" || y != "|")
{
cin >> x;
cin >> y;
cout << x << endl;
cout << y << endl;
}
return 0;
}
正如人们在评论和 paxdiablo 的回答中指出的那样,您有两个未初始化的变量,您正在尝试输入一个 int,然后将其与 char 进行比较。
我们可以使用 cin.peek()
查看下一个字符并检查它是否为“|”,而不是尝试将输入的 int 与 char 进行比较在阅读之前。
#include <iostream>
int main()
{
int x, y;
while(std::cin.peek() != '|') //cin.peek() will return the next character to be read
{
std::cin >> x >> y;
std::cout << x << ' ' << y << '\n';
std::cin.ignore(); //ignore whitespace/linebreak character left by extraction (>> operator)
}
}