QQ登录

只需一步,快速开始

登录 | 立即注册 | 找回密码

主题

帖子

荣誉

VIP至尊会员

Rank: 15Rank: 15Rank: 15

积分
29
查看: 83|回复: 4

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

[复制链接]
最佳答案
0 
累计签到:8 天
连续签到:1 天
七月水水 发表于 5 天前 834 | 显示全部楼层 |阅读模式

马上注册加入鱼C,享用更多服务吧^_^

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

x
其中cin.clear();更改cin输入错误的状态
                        函数cin.sync();清空缓冲流
                        函数cin.ignore(1024, '\n');指定清除缓冲流数据的长度
*****************************************************************
        然而,函数cin.sync();怎么不起作用了呢??
最佳答案
5 天前
https://www.zhihu.com/question/40160488
20180516192831.png
20180516192903.png
楼层
跳转到指定楼层
最佳答案
278 
累计签到:490 天
连续签到:1 天
人造人 发表于 5 天前 | 显示全部楼层
贴代码
最佳答案
0 
累计签到:8 天
连续签到:1 天
七月水水  楼主| 发表于 5 天前 | 显示全部楼层
#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");
}
最佳答案
278 
累计签到:490 天
连续签到:1 天
人造人 发表于 5 天前 | 显示全部楼层    本楼为最佳答案   
https://www.zhihu.com/question/40160488
最佳答案
0 
累计签到:8 天
连续签到:1 天
七月水水  楼主| 发表于 5 天前 | 显示全部楼层
原回答中只解释了 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 下一条

    移动客户端下载(未启用)
    微信公众号

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备11014136号

Copyright 2018 鱼C论坛 版权所有 All Rights Reserved.

Powered by Discuz! X3.1 Copyright
© 2001-2018 Comsenz Inc.    All Rights Reserved.

小黑屋|手机版|Archiver|鱼C工作室 ( 粤公网安备 44051102000370号 | 粤ICP备11014136号

GMT+8, 2018-5-21 20:56

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