setbuf函数的相关问题(与缓冲有关吧)

给你糖别哭 2014-05-28 04:02:13
嗯,把《C Traps and Pitfalls》浏览完了,实践里面一些代码时遇到了一些问题。
其中之一,就是这个setbuf的问题了,感觉与缓冲有关,但是没找到突破点。
代码:
 
#include <iostream>
#include <cstdio>
using namespace std;

int main()
{
int c;
char buf[ 32 ];
setbuf( stdout, buf );

while (( c=getchar()) != EOF )
putchar(c);

// cin.get();
return 0;
}

先说明一下问题情况:
1、VC++6.0运行上面代码
输入:123【Enter】^Z【Enter】。
输出:X蜙【空格】。
图:
2、将buf字符数组大小改为宏定义的BUFSIZ,VC++6.0运行上面代码
输入:12345【Enter】^Z【Enter】。
输出:1234【空格】【空格】。
图:
即不正常,输入再多点的字符输出更不正常了;
3、将buf字符数组大小改为1024,VC++6.0运行上面代码
输入:123456790【Enter】^Z【Enter】。
输出:123456790【换行】。
图:
看似正常是吧?其实输出比例2多输出了换行,那么换行到底是输出正确还是不输出正确呢?
4、VS2008运行原代码
输入:123【Enter】^Z【Enter】。
输出:【心,ASCII为3的符号】O【随机字符】。
后面的为随机字符,由于是vs,不加cin.get()的话结果一闪而过,这是进行多次得到的结果,无法截图,可自行实验。
至于加上cin.get()或者system("pause"),前者后面会有说明,后者经实验不行,会先结束程序再在结束dos对话框瞬间闪现结果。水平有限,表示不理解,欢迎探讨;
5、嗯,其他的不多说,请自己在VS环境下运行buf字符shuzu分别为BUFSIZ和1024的程序吧,比VC++6.0还要不堪,可能跟其程序结束机理不同有关吧;
6、接着上面说的,在结尾加了cin.get()函数后,终于出现了正确结果,且每个输出都会有换行
比如输入:123【Enter】123【Enter】^Z【Enter】。
输出:123【换行】123【换行】。
再按一下【Enter】键,程序结束。
图:
就是说输出换行是正确的?这个我也不清楚,求解惑!
也在VC++6.0调试了下,但不得果。
嗯,就这些了,水平有限,欢迎探讨!
...全文
160 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
给你糖别哭 2014-05-28
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
这些函数都是开放源代码的,为何不单步到对应的源代码中一探究竟呢?
嗯,试试
赵4老师 2014-05-28
  • 打赏
  • 举报
回复
这些函数都是开放源代码的,为何不单步到对应的源代码中一探究竟呢?
给你糖别哭 2014-05-28
  • 打赏
  • 举报
回复
引用 3 楼 mujiok2003 的回复:
[quote=引用 2 楼 dongmuyang 的回复:] [quote=引用 1 楼 mujiok2003 的回复:] buf大小应该至少为BUFSIZE, 否则行为未定义。
嗯,那为什么是BUFSIZ还是出错呢[/quote] 加上fflush试试

 
#include <iostream>
#include <cstdio>
using namespace std;

int main()
{
        int c;
        char buf[BUFSIZ];
        setbuf(stdout, buf);

        while (( c=getchar()) != EOF )
                putchar(c);
        fflush(stdout);
        return 0;
}
[/quote] 嗯,可以。能说下原因吗,还有之前有错的原因~ 不清除缓冲的话,输出为什么会错误。 还有,有cin.get()的程序是不是先把缓冲清除了在接收一个字符,所以效果就跟用了fflush一样。 谢谢了
mujiok2003 2014-05-28
  • 打赏
  • 举报
回复
引用 2 楼 dongmuyang 的回复:
[quote=引用 1 楼 mujiok2003 的回复:] buf大小应该至少为BUFSIZE, 否则行为未定义。
嗯,那为什么是BUFSIZ还是出错呢[/quote] 加上fflush试试

 
#include <iostream>
#include <cstdio>
using namespace std;

int main()
{
        int c;
        char buf[BUFSIZ];
        setbuf(stdout, buf);

        while (( c=getchar()) != EOF )
                putchar(c);
        fflush(stdout);
        return 0;
}
给你糖别哭 2014-05-28
  • 打赏
  • 举报
回复
引用 1 楼 mujiok2003 的回复:
buf大小应该至少为BUFSIZE, 否则行为未定义。
嗯,那为什么是BUFSIZ还是出错呢
mujiok2003 2014-05-28
  • 打赏
  • 举报
回复
buf大小应该至少为BUFSIZE, 否则行为未定义。
打开下面链接,直接免费下载资源: https://renmaiwang.cn/s/ska3s C语言清空输入缓冲区在标准输入(stdin)情况下的使用C语言中,输入缓冲区是指标准输入(stdin)中的缓冲区,当用户输入数据时,数据会先存储在缓冲区中,然后再被读取和处理。但是,如果不正确地清空输入缓冲区,可能会导致程序出现问题。因此,本文将介绍C语言清空输入缓冲区在标准输入(stdin)情况下的使用。在C语言中,有多种方法可以清空输入缓冲区。第一种方法是使用fflush函数,该函数可以清空缓冲区,但是这种方法容易出错,不建议使用。第二种方法是使用scanf函数来读取缓冲区中的数据,但是这种方法也容易失效。第三种方法是使用setbuf函数,该函数可以使stdin输入流由默认缓冲区转为无缓冲区,但是这种方法也不能完美地清空缓冲区。一种可行的方法是使用getchar函数来清空缓冲区,该函数可以不断地获取缓冲中字符,直到获取的字符是“\n”或文件结尾符EOF为止。这种方法可以完美地清空输入缓冲区,并具备可移植性。在程序1中,我们可以看到,输入一个数字,然后输入一个字符,但是直接输出了“hello bit”,这是因为在点击回车(‘\n’)时,相当于输入了一个字符,那么我们需要进行清空缓冲区处理。在程序2中,我们使用了fflush函数来清空缓冲区,但是这种方法容易出错,不建议使用。在程序3中,我们使用了getchar函数来清空缓冲区,这种方法可以完美地清空输入缓冲区,并具备可移植性。C语言中清空输入缓冲区的方法有多种,但是使用getchar函数来清空缓冲区是最可靠和最可移植的方法。知识点:* 输入缓冲区是指标准输入(stdin)中的缓冲区* 清空输入缓冲区是指清空缓冲区中的数据* 使用fflush函数清空缓冲区容易出错,不建议使用* 使用scanf函数清空缓冲区容易失效* 使用setbu

65,209

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧