对于此代码:
#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
using namespace std;
#define p(a) cout << "|" << a << "|" << endl
int main() {
char a[100];
char b[100];
cin.getline(a, 4, '\n');
cin >> b;
p(a);
p(b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我的输入是“1234”
1234
Run Code Online (Sandbox Code Playgroud)
我有下一个输出:
|123|
||
Run Code Online (Sandbox Code Playgroud)
但我知道使用 getline,我得到三个元素:"123"它发送到a变量添加到\0字符的末尾。以同样的方式,剩余的字符"4\n"留在缓冲区中。那么为什么在接下来"cin>>"它没有被复制到b变量中?,为什么b是null?
如果std::istream::getline不能将整行(并终止空值)放入给定的缓冲区,它会设置一个错误标志并且在错误被清除之前变得不可读。
std::istream::get的第四个重载是此用例的更好选择,因为如果整行未被消耗,它不会引发标志。
代替
cin.getline(a, 4, '\n');
Run Code Online (Sandbox Code Playgroud)
和
cin.get(a, 4, '\n');
Run Code Online (Sandbox Code Playgroud)
在任何 IO 事务之后,在继续之前测试流的状态,以便您知道是否值得按计划进行,或者事务是否失败并且您必须执行其他操作(例如clear错误并重试)。例如,您可以
if (cin)
{
// safe to act upon the values read
}
Run Code Online (Sandbox Code Playgroud)
或者,因为几乎所有流函数都返回流以便于 IO 链接,
if (cin.get(a, 4, '\n'))
{
// safe to act upon the values read
}
Run Code Online (Sandbox Code Playgroud)
自从我提到它,链接是允许代码的魔法
std::cin >> a >> b >> c;
Run Code Online (Sandbox Code Playgroud)
并且与成功的读取测试a,b和c
if (std::cin >> a >> b >> c)
{
// safe to do stuff with a, b, and c
}
Run Code Online (Sandbox Code Playgroud)