为什么 cin 在使用 getline 后没有获取缓冲区数据?
Why cin is not getting buffer data after using getline?
到此代码:
#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;
}
如果我的输入是“1234”
1234
我有下一个输出:
|123|
||
但我知道使用 getline,我得到了三个元素:"123"
并且它发送到 a
变量并在末尾添加 [=15=]
字符。同理,剩余字符"4\n"
留在缓冲区中。那么为什么在接下来的"cin>>"
中没有复制到b
变量中呢?为什么b
是null
?
如果std::istream::getline
不能将整行(和终止空)放入给定的缓冲区,它会设置一个错误标志并变得不可读,直到错误被清除。
std::istream::get
的第四个重载对此 use-case 是一个更好的选择,因为如果整行未被消耗它不会引发标志。
替换
cin.getline(a, 4, '\n');
和
cin.get(a, 4, '\n');
不相关的推荐:
在任何 IO 事务之后,在继续之前测试流的状态,以便您知道是否值得按计划进行,或者事务是否失败并且您必须执行其他操作(例如 clear
错误并重试)。例如,您可以
if (cin)
{
// safe to act upon the values read
}
或者,因为几乎所有流函数 return 流都用于轻松链接 IO,
if (cin.get(a, 4, '\n'))
{
// safe to act upon the values read
}
既然我提到了它,链接就是允许像这样的代码的魔法
std::cin >> a >> b >> c;
以及成功读取 a
、b
和 c
的测试
if (std::cin >> a >> b >> c)
{
// safe to do stuff with a, b, and c
}
到此代码:
#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;
}
如果我的输入是“1234”
1234
我有下一个输出:
|123|
||
但我知道使用 getline,我得到了三个元素:"123"
并且它发送到 a
变量并在末尾添加 [=15=]
字符。同理,剩余字符"4\n"
留在缓冲区中。那么为什么在接下来的"cin>>"
中没有复制到b
变量中呢?为什么b
是null
?
如果std::istream::getline
不能将整行(和终止空)放入给定的缓冲区,它会设置一个错误标志并变得不可读,直到错误被清除。
std::istream::get
的第四个重载对此 use-case 是一个更好的选择,因为如果整行未被消耗它不会引发标志。
替换
cin.getline(a, 4, '\n');
和
cin.get(a, 4, '\n');
不相关的推荐:
在任何 IO 事务之后,在继续之前测试流的状态,以便您知道是否值得按计划进行,或者事务是否失败并且您必须执行其他操作(例如 clear
错误并重试)。例如,您可以
if (cin)
{
// safe to act upon the values read
}
或者,因为几乎所有流函数 return 流都用于轻松链接 IO,
if (cin.get(a, 4, '\n'))
{
// safe to act upon the values read
}
既然我提到了它,链接就是允许像这样的代码的魔法
std::cin >> a >> b >> c;
以及成功读取 a
、b
和 c
if (std::cin >> a >> b >> c)
{
// safe to do stuff with a, b, and c
}