鱼C论坛

 找回密码
 立即注册
查看: 2083|回复: 4

[已解决]一个输入流的有关问题,求高手解答

[复制链接]
发表于 2018-5-16 19:43:09 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
其中cin.clear();更改cin输入错误的状态
                        函数cin.sync();清空缓冲流
                        函数cin.ignore(1024, '\n');指定清除缓冲流数据的长度
*****************************************************************
        然而,函数cin.sync();怎么不起作用了呢??
最佳答案
2018-5-16 20:19:03
https://www.zhihu.com/question/40160488
20180516192831.png
20180516192903.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-5-16 20:00:43 | 显示全部楼层
贴代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-5-16 20:05:43 | 显示全部楼层
#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");
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-5-16 20:19:03 | 显示全部楼层    本楼为最佳答案   
https://www.zhihu.com/question/40160488
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-5-16 20:47:27 | 显示全部楼层
原回答中只解释了 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。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 18:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表