一个输入流的有关问题,求高手解答
其中cin.clear();更改cin输入错误的状态函数cin.sync();清空缓冲流
函数cin.ignore(1024, '\n');指定清除缓冲流数据的长度
*****************************************************************
然而,函数cin.sync();怎么不起作用了呢?? 贴代码 #include <iostream>
int main()
{
using namespace std;
int a;
while (1)
{
cin >> a;
if (!cin)
{
cout << "输入有误,请重新输入!\n";
cin.clear();
cin.sync();
//cin.ignore(1024, '\n');
}
else {
cout<<a<<endl; break;
}
}
system("pause");
} https://www.zhihu.com/question/40160488 原回答中只解释了 std::ifstream 的问题,但最关键的在 std::cin 上情况则没有讲清楚。关于 std::ifstream 上调用 sync() 的解释无误,但针对 std::cin「数据源」的解释是存在错误的,抱歉。
对于 std::cin 这些标准库「自带」的输入流来说,调用 sync() 是「实现定义」的行为。所以此处调了 sync() 以后清空、恢复原状、什么都不干都是可以的,如果没有得到预期的效果的话,可以查看自己的编译器(标准库实现)的说明文档,上面应该有写明它所使用的是哪种行为。
具体可以参考:cppreference.com
p.s. 感谢
@龙时雨
的私信
以下为原回答:
首先说一句,学好英语是做好程序员的必要条件。sync 是「同步」的意思,而不是题目中的「清空」。
把 std::cin 和 stdin 分开看,就会比较好理解 sync。
为了更好理解,以 std::ifstream f("test.txt"); 为例,对象 f 和磁盘上的文件 test.txt 就是两个相关联但不同的东西。f 有自己的缓冲区用来缓冲从 test.txt 读取的内容。而 sync() 则是强制将 test.txt 的内容「同步」到缓冲区。
比如 test.txt 内容本来是 abc。f 被创建后缓冲区内可能就直接加载了这三个字符,今后的读写就都直接从缓冲区,而非文件本身做了。这样一来,如果此时 test.txt 的内容立即被另一个程序改成了 123,从 f 对象里读取的内容仍旧是 abc。但如果调用 sync(),则缓冲区会同步成 123。
---
至此,你会发现 sync 对题目里举例的这种情况确实不可能有任何作用。
第一次 cin >> i 失败后,你输入的 a 仍然残留在输入缓冲区中,下一次的 cin >> i 发现输入缓冲区中残留的 a 就直接尝试处理,而不向你请求输入了。
所以需要用 ignore() 忽略这个残留的字符 a。
页:
[1]