setvbuf给stdin设置无缓冲或者满缓冲,为什么最后效果都是行缓冲?

六道佩恩 2018-09-28 09:48:40
最令我奇怪的是设置满缓冲的时候,假如我设置缓冲区长度10,那么如果我输入abcdefghijklmnopqrst,字符串还是正常接收,但是缓冲区的内容是\n\nmnopqrst,这我能推测出原因,总共输入abcdefghijklmnopqrst\n\n,缓冲区首先装了abcdefghij,满了,然后重新装klmnopqrst,满了,然后重新装\n\n,\n\n覆盖kl,所以是这个结果,可是,缓冲区都满了几次了,接收函数怎么没反应呢?
...全文
603 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_45424883 2019-12-05
  • 打赏
  • 举报
回复
可以试下禁用终端的标准模式ICANON: struct termios tio; tcgetattr(0, &tio); tio.c_lflag &= ~(ICANON) | ECHO; tio.c_cc[VTIME] = 0; tio.c_cc[VMIN] = 1; tcsetattr(0, TCSADRAIN, &tio); 可以参考https://blog.csdn.net/mr_raptor/article/details/8349323的说明
六道佩恩 2019-09-03
  • 打赏
  • 举报
回复
引用 15 楼 turmary 的回复:
这个是系统提供的缓冲区,而stdio库的setbuf,setvbuf只是操作C库的缓冲,不管系统的。
我想了解的就是C函数,并不是单纯地想实现某种功能
turmary 2019-09-02
  • 打赏
  • 举报
回复
这个是系统提供的缓冲区,而stdio库的setbuf,setvbuf只是操作C库的缓冲,不管系统的。
turmary 2019-09-02
  • 打赏
  • 举报
回复
Windows下可以看
https://stackoverflow.com/questions/51726140/console-with-enable-line-input-doesnt-pass-r
https://docs.microsoft.com/en-us/windows/console/setconsolemode

Linux可以看 <Unix环境高级编程>
千寻1997 2019-08-28
  • 打赏
  • 举报
回复
引用 12 楼 六道佩恩 的回复:
[quote=引用 11 楼 千寻1997 的回复:] 这个问题我也遇到了,使用setbuf就是你要的效果
其中的原因您知道吗?[/quote]我不知道。当时我用setbuf试了一下,有一次成功了,然后,我就去试setvbuf,后来看到你的问题,就回复了。我想复现setbuf设置输入流为空又失败了。所以setbuf可能不行。
千寻1997 2019-08-27
  • 打赏
  • 举报
回复
这个问题我也遇到了,使用setbuf就是你要的效果
六道佩恩 2019-08-27
  • 打赏
  • 举报
回复
引用 11 楼 千寻1997 的回复:
这个问题我也遇到了,使用setbuf就是你要的效果
其中的原因您知道吗?
赵4老师 2018-11-06
  • 打赏
  • 举报
回复
提醒stdin是开源的。
super_miker 2018-11-06
  • 打赏
  • 举报
回复
用getch解决问题
ShowMeYourCode 2018-11-01
  • 打赏
  • 举报
回复
Stdin确实改不成no buffer,操作系统的原因吧。底层的东西不是很懂。
六道佩恩 2018-09-29
  • 打赏
  • 举报
回复
引用 6 楼 zangfong 的回复:
我。。。
你现在是从标准输入读取,如果不回车,你在cmd窗口中的输入怎么才算结束?你的程序不就是在等待你的输入终止么。当然是要等你按了回车才继续的啊。
滞留区只是玩笑而已。
试试下面这段,从标准输入获取,你可以试试输入"abcdefghijk"然后回车看看。
#include<stdio.h>
#include<windows.h>
char buff[10];
int main()
{
int c;
setvbuf(stdout, buff, _IOFBF, 10);
while(putchar(getchar())!='\n');
printf("done!");
Sleep(2000);
fflush(stdout);

return 0;
}



[quote=引用 4 楼 weixin_39158150 的回复:]
[quote=引用 2 楼 zangfong 的回复:]
我试了下,至少可以正常显示,不明白你所说的接收函数没反应的意思。你也可以写到文件试试。

还有,按照你的输入“abcdefghijklmnopqrst\n\n”,最后缓冲区里面也就只剩"\n\n"了,如果是“\n\nmnopqrst”,那缓冲区还叫缓冲区么,那不是滞留区了么。。。
#include<stdio.h>
#include<windows.h>
char buff[10];

int main()
{
fprintf(stdout, "启用满缓冲\n");
setvbuf(stdout, buff, _IOFBF, 10);

fprintf(stdout, "abcdefghijklmnopqrst\n\n...done");
Sleep(2000);

return(0);
}


老哥,我觉得你没明白我的意思啊。我试的是stdin啊,如果无缓冲的话,那个getchar接收时,应该输入一个字符后就自动接收了,但是仍然是等到按了回车后才开始读取的。满缓冲也是,我输入的内容已经超过缓冲区很多了,仍然没有开始读取,而是等我按了回车后才开始读取的。我不明白你说的滞留区是什么意思,只是实际测试是如此,如果输入太多缓冲区不够装的话,他就会来回装填直到装完缓冲区。其实,我说一个我个人的看法不知道你觉得如何,我认为这个缓冲区是只属于我们这个程序的缓冲区,系统对于键盘输入有自己的缓冲区,那么我们的缓冲区只是在按了回车后从那个缓冲区复制过来的数据而已。[/quote][/quote]

老哥。。。我要改变的就是标准输入啊。。。我实在不明白你的程序到底想干啥
zangfong 2018-09-29
  • 打赏
  • 举报
回复
我。。。 你现在是从标准输入读取,如果不回车,你在cmd窗口中的输入怎么才算结束?你的程序不就是在等待你的输入终止么。当然是要等你按了回车才继续的啊。 滞留区只是玩笑而已。 试试下面这段,从标准输入获取,你可以试试输入"abcdefghijk"然后回车看看。
#include<stdio.h>
#include<windows.h>
char buff[10];
int main()
{
    int c;
    setvbuf(stdout, buff, _IOFBF, 10);
    while(putchar(getchar())!='\n');
    printf("done!");
    Sleep(2000);
    fflush(stdout);

    return 0;
}
引用 4 楼 weixin_39158150 的回复:
[quote=引用 2 楼 zangfong 的回复:] 我试了下,至少可以正常显示,不明白你所说的接收函数没反应的意思。你也可以写到文件试试。 还有,按照你的输入“abcdefghijklmnopqrst\n\n”,最后缓冲区里面也就只剩"\n\n"了,如果是“\n\nmnopqrst”,那缓冲区还叫缓冲区么,那不是滞留区了么。。。
#include<stdio.h>
#include<windows.h>
char buff[10];

int main()
{
   fprintf(stdout, "启用满缓冲\n");
   setvbuf(stdout, buff, _IOFBF, 10);

   fprintf(stdout, "abcdefghijklmnopqrst\n\n...done");
   Sleep(2000);

   return(0);
}
老哥,我觉得你没明白我的意思啊。我试的是stdin啊,如果无缓冲的话,那个getchar接收时,应该输入一个字符后就自动接收了,但是仍然是等到按了回车后才开始读取的。满缓冲也是,我输入的内容已经超过缓冲区很多了,仍然没有开始读取,而是等我按了回车后才开始读取的。我不明白你说的滞留区是什么意思,只是实际测试是如此,如果输入太多缓冲区不够装的话,他就会来回装填直到装完缓冲区。其实,我说一个我个人的看法不知道你觉得如何,我认为这个缓冲区是只属于我们这个程序的缓冲区,系统对于键盘输入有自己的缓冲区,那么我们的缓冲区只是在按了回车后从那个缓冲区复制过来的数据而已。[/quote]
六道佩恩 2018-09-29
  • 打赏
  • 举报
回复
引用 1 楼 cfjtaishan 的回复:
https://blog.csdn.net/wangjiaoyu250/article/details/8629136

https://blog.csdn.net/fjt19900921/article/details/8122313

可以看一下这两个例子

我觉得第二个帖子说的是错的,如果按他说的交接控制权,那么其实就是在说程序之间用的输入缓冲区是同一个,如果是这样的话,那我同时运行两个程序,那是不是我在一个程序输入另一个程序也可以读取数据?还有就是这两篇文章跟我的问题没什么关系,不过还是要谢谢你。
六道佩恩 2018-09-29
  • 打赏
  • 举报
回复
引用 2 楼 zangfong 的回复:
我试了下,至少可以正常显示,不明白你所说的接收函数没反应的意思。你也可以写到文件试试。

还有,按照你的输入“abcdefghijklmnopqrst\n\n”,最后缓冲区里面也就只剩"\n\n"了,如果是“\n\nmnopqrst”,那缓冲区还叫缓冲区么,那不是滞留区了么。。。
#include<stdio.h>
#include<windows.h>
char buff[10];

int main()
{
fprintf(stdout, "启用满缓冲\n");
setvbuf(stdout, buff, _IOFBF, 10);

fprintf(stdout, "abcdefghijklmnopqrst\n\n...done");
Sleep(2000);

return(0);
}


老哥,我觉得你没明白我的意思啊。我试的是stdin啊,如果无缓冲的话,那个getchar接收时,应该输入一个字符后就自动接收了,但是仍然是等到按了回车后才开始读取的。满缓冲也是,我输入的内容已经超过缓冲区很多了,仍然没有开始读取,而是等我按了回车后才开始读取的。我不明白你说的滞留区是什么意思,只是实际测试是如此,如果输入太多缓冲区不够装的话,他就会来回装填直到装完缓冲区。其实,我说一个我个人的看法不知道你觉得如何,我认为这个缓冲区是只属于我们这个程序的缓冲区,系统对于键盘输入有自己的缓冲区,那么我们的缓冲区只是在按了回车后从那个缓冲区复制过来的数据而已。
六道佩恩 2018-09-29
  • 打赏
  • 举报
回复
引用 2 楼 zangfong 的回复:
我试了下,至少可以正常显示,不明白你所说的接收函数没反应的意思。你也可以写到文件试试。

还有,按照你的输入“abcdefghijklmnopqrst\n\n”,最后缓冲区里面也就只剩"\n\n"了,如果是“\n\nmnopqrst”,那缓冲区还叫缓冲区么,那不是滞留区了么。。。
#include<stdio.h>
#include<windows.h>
char buff[10];

int main()
{
fprintf(stdout, "启用满缓冲\n");
setvbuf(stdout, buff, _IOFBF, 10);

fprintf(stdout, "abcdefghijklmnopqrst\n\n...done");
Sleep(2000);

return(0);
}

getchar、scanf一类的输入函数
zangfong 2018-09-29
  • 打赏
  • 举报
回复
我试了下,至少可以正常显示,不明白你所说的接收函数没反应的意思。你也可以写到文件试试。 还有,按照你的输入“abcdefghijklmnopqrst\n\n”,最后缓冲区里面也就只剩"\n\n"了,如果是“\n\nmnopqrst”,那缓冲区还叫缓冲区么,那不是滞留区了么。。。
#include<stdio.h>
#include<windows.h>
char buff[10];

int main()
{
   fprintf(stdout, "启用满缓冲\n");
   setvbuf(stdout, buff, _IOFBF, 10);

   fprintf(stdout, "abcdefghijklmnopqrst\n\n...done");
   Sleep(2000);

   return(0);
}

69,381

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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