我想向 C++ 程序输入十六进制字符。为此,我使用命令
echo -e "2\n\x01\x00\x01\x00" | ./program 4 /dev/stdin
输入
2\n
应转到 cin >> op
且 \x01\x00\x01\x00
将转到 read
函数(这就是为什么我将 4
和 /dev/stdin
作为程序的参数)。
这会导致奇怪的行为 - 菜单在无限循环中一遍又一遍地打印。即使简单地使用
echo -e "1\n" | ./program 4 /dev/stdin
导致相同的循环。例如,如果我跑步,
echo -e "1" | ./program 4 /dev/stdin
我仍然遇到无限循环,但这次
in case No. 1
行也被打印。
我想知道为什么会发生这种情况,如何解决这个问题 - 如何使程序正确理解我的输入。请注意,该解决方案应支持在回显中输入空字节 (
\x00
),因为这是我想要提供给 read
函数的数据的一部分(例如。
注释:
echo
的相同输入,我希望它使用它并终止或等待输入。echo
和stdin
),但我的问题是根本性的,而不是寻找解决方法(假设例如您没有权限写入除stdin
之外的任何文件)。2
转到第一个 cin
调用,以及十六进制值转到 read
。#include <fcntl.h>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
using namespace std;
int main(int argc, char* argv[]){
size_t len;
char* data;
unsigned int op;
while(1){
cout << "1. use\n2. after\n";
cin >> op;
switch(op){
case 1:
cout << "in case No. 1" << endl;
break;
case 2:
len = atoi(argv[1]);
data = new char[len];
read(open(argv[2], O_RDONLY), data, len);
cout << "your data is allocated" << endl;
break;
default:
break;
}
}
return 0;
}
当您尝试在 EOF 处读取文件或管道时也不例外。它只是设置
eofbit
的 failbit
(和 cin
?)标志。来自cppreference:
通过修改内部状态标志来发出错误信号,(3)除外,它从不设置任何标志(但应用的特定操纵器可能会设置)
如果您希望循环在发生这种情况时结束,则必须明确检查这一点。常见的习惯用法是像
那样构造循环while (cin >> op) {
// code
}
您还可以更明确地检查:
if (!cin.good()) {
break;
}
发生这种情况时,它不会更新您要提取到的变量,因此它保留其先前的值。结果,您在
switch
中不断重复相同的情况,并且出现无限循环。