关于缓冲区或者说字符串显示的一点疑问。

yiruirui0507 2010-11-28 06:07:58
int main()
{
int num;
cout<<"enter an interger:";
cin>>num;
cout<<endl;
return 0;
}
字符串的显示都是先输入到缓冲区,等缓冲区满了,或者ENDL,ENDS,FLUSH,\N等等些情况才会去刷新缓冲区。
但是这里的 cout<<"enter an interger:";
却能够显示到屏幕上,有些人猜测COUT的缓冲区是1个字节?我认为这个绝对不可能。
但是又想不太明白这里为何就能显示出来呢?我也认为缓冲区不可能填满,但是这里又没有刷新的标志符号。这里是否有什么机制?
特地到论坛求助,大家可以尽情发挥!3q!
...全文
265 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
yiruirui0507 2010-11-30
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 bluewanderer 的回复:]
操作系统里一般一切设计输入输出的对象都会被作为文件看待,或者说任何设备都是逻辑上的文件,输入输出的缓冲区就是FILE的那个缓冲区。
[/Quote]多谢解释!你是不是看过LINUX内核啊?
bluewanderer 2010-11-30
  • 打赏
  • 举报
回复
操作系统里一般一切设计输入输出的对象都会被作为文件看待,或者说任何设备都是逻辑上的文件,输入输出的缓冲区就是FILE的那个缓冲区。
yiruirui0507 2010-11-30
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 hqin6 的回复:]
C/C++ code

首先声明,我没有vs系列的编译器,所以,以下结果都是在ubuntu下的gcc version 4.4.5实验得到:
#include <iostream>
using namespace std;
int main()
{
int num;
cout<<"enter an interger:";
_exit(0);
cin……
[/Quote]
恩,非常感谢了,最后问你一个小问题,你用GCC测试一下看看UBUNTU下的COUT,CIN的缓冲区大小各是多少,谢谢。可以使用
int main()
{
FILE *fp = stdout;

printf("%d\n", fp->_bufsiz);
}
这个来测试一下,_bufsiz就是缓冲区的大小,不过貌似是文件缓冲区的大小,因为是文件类型的变量,3Q!
文件的确是全缓冲!
太乙 2010-11-30
  • 打赏
  • 举报
回复

首先声明,我没有vs系列的编译器,所以,以下结果都是在ubuntu下的gcc version 4.4.5实验得到:
#include <iostream>
using namespace std;
int main()
{
int num;
cout<<"enter an interger:";
_exit(0);
cin>>num;
cout<<endl;
return 0;
}

运行后,没有任何输出,说明_exit没有进行输出缓冲区的刷新

#include <iostream>
using namespace std;
int main()
{
int num;
cout<<"enter an interger:";
cin>>num;
_exit(0);
cout<<endl;
return 0;
}
有数据输出,说明cin导致了cout的缓冲区刷新

#include <iostream>
using namespace std;
int main()
{
int num;
cout<<"enter an interger:";
cout << "\n";
_exit(0);
cin>>num;
cout<<endl;
return 0;
}
有输出,说明\n可以导致缓冲区的刷新


另外,将第三个程序重定向到文件中,则无输出(因为文件是全缓冲,而命令行是行缓冲)
但是将\n改为endl,则有输出(因为endl不仅输出换行,还强制刷新缓冲区)

再次强调:vs系列如何实现缓冲区的我不是很清楚,上面只是在gcc下实验得出。。。。

太乙 2010-11-30
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 yiruirui0507 的回复:]

引用 22 楼 hqin6 的回复:
引用 15 楼 yiruirui0507 的回复:

引用 13 楼 hqin6 的回复:
lz可以试试下面的代码:

int main()
{
int num;
cout<<"enter an interger:";
_exit(0);//----这里_exit函数不会去刷新缓冲区而直接调用到系统级的退出,所以上面的cout是打印不出来……
[/Quote]
就两点:
1、输入缓冲区有新的数据进来前,需要刷新输出缓冲区
2、我不大了解vs系列对缓冲区的具体实现。但是在linux/unix上,确实是这样的。lz可以看我上面贴出来的代码./a.out运行以后,没有任何输出,正因为_exit不刷新缓冲区。。。
bluewanderer 2010-11-29
  • 打赏
  • 举报
回复
单就下面的输出来说...不管有没有缓冲输出都应该是那样...

如果算上输入,别忘了stdin是有缓冲,并且getchar是有回显的。不过C库回显怎么实现的我发现我还真不知道TvTb stdin的缓冲里很有可能是回显之后的东西,猜测,懒得看了
yiruirui0507 2010-11-29
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 bluewanderer 的回复:]
1234
149250351452Press any key to continue . . .

既然有一个缓冲的就有可能有第二个,linux可能因为考虑到远程登录所以缓冲。说到底windows里printf基本上没可能直接写到远程机,另一方面微软的telnet自己本来也没缓冲x_xb

main() 难道你在turbo C里跑的?
[/Quote]
我在VS08下跑的,这个不正说明了COUT有缓冲吗?如果没缓冲,那这里如何理解?
putchar是直接发送到屏幕,但是屏幕依然没显示,这里也想不太明白?
bluewanderer 2010-11-29
  • 打赏
  • 举报
回复
1234
149250351452Press any key to continue . . .

既然有一个缓冲的就有可能有第二个,linux可能因为考虑到远程登录所以缓冲。说到底windows里printf基本上没可能直接写到远程机,另一方面微软的telnet自己本来也没缓冲x_xb

main() 难道你在turbo C里跑的?
yiruirui0507 2010-11-29
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 bluewanderer 的回复:]
Linux上的确有缓冲的意思
[/Quote]

不只LINUX上有,你看下面这段代码如何解释?


main()
{
int ch;
while ((ch=getchar()) != '\n' )
{
putchar(ch);
cout<<ch;
}
}

赵4老师 2010-11-29
  • 打赏
  • 举报
回复
摒弃cin、cout;
使用scanf,printf
bluewanderer 2010-11-29
  • 打赏
  • 举报
回复
Linux上的确有缓冲的意思
yiruirui0507 2010-11-29
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 hqin6 的回复:]
引用 15 楼 yiruirui0507 的回复:

引用 13 楼 hqin6 的回复:
lz可以试试下面的代码:

int main()
{
int num;
cout<<"enter an interger:";
_exit(0);//----这里_exit函数不会去刷新缓冲区而直接调用到系统级的退出,所以上面的cout是打印不出来的。。。
//一般来说,cout输出到终……
[/Quote]

什么意思?
太乙 2010-11-29
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 yiruirui0507 的回复:]

引用 13 楼 hqin6 的回复:
lz可以试试下面的代码:

int main()
{
int num;
cout<<"enter an interger:";
_exit(0);//----这里_exit函数不会去刷新缓冲区而直接调用到系统级的退出,所以上面的cout是打印不出来的。。。
//一般来说,cout输出到终端,一般是行缓冲,当然重定向到文件另当别论。。。
ci……
[/Quote]

root@root-wpc:~$ ./a.out
root@root-wpc:~$ cat t.cpp
#include <iostream>
using namespace std;
int main()
{
int num;
cout<<"enter an interger:";
_exit(0);
cin>>num;
cout<<endl;
return 0;
}
root@root-wpc:~$ g++ t.cpp
root@root-wpc:~$ ./a.out
root@root-wpc:~$
root@root-wpc:~$ uname -a
Linux root-wpc 2.6.35-22-generic #33-Ubuntu SMP Sun Sep 19 20:34:50 UTC 2010 i686 GNU/Linux
root@root-wpc:~$ gcc -v
Using built-in specs.
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.4.4-14ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5)
root@root-wpc:~$


bluewanderer 2010-11-28
  • 打赏
  • 举报
回复
不是所有代码都能在VC里跟踪到的,有一部分初始化代码并不对应源代码,而且这个完全有可能是直接初始化的全局变量
yiruirui0507 2010-11-28
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 bluewanderer 的回复:]
C/C++ code
if (_Myios::tie() != 0)
_Myios::tie()->flush();



stdin刷stdout可能单纯是STL级别的实现。在C级别实现太蛋疼了。
[/Quote]
你好,根据你的代码我修改了变成stdin的了:
#include <stdio.h>

int main()
{
FILE *fp = stdout;

printf("%d\n", fp->_bufsiz);
}
变成:
int main()
{
FILE *fp = stdin;

printf("%d\n", fp->_bufsiz);
}
这里输出4096,我的意思是,这个4096是在哪里定义的?在哪里设置的?
我们可以不可以把STDOUT的也设置一个数用来测试一下?
我跟踪了半天也没找到4096是在哪里赋值的,你看。。。。有办法没?
bluewanderer 2010-11-28
  • 打赏
  • 举报
回复
			if (_Myios::tie() != 0)
_Myios::tie()->flush();


stdin刷stdout可能单纯是STL级别的实现。在C级别实现太蛋疼了。
qq120848369 2010-11-28
  • 打赏
  • 举报
回复
cin.tie(&cout); 


你可以自己来设定刷新依赖关系,如上.
太乙 2010-11-28
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 yiruirui0507 的回复:]

引用 13 楼 hqin6 的回复:
lz可以试试下面的代码:

int main()
{
int num;
cout<<"enter an interger:";
_exit(0);//----这里_exit函数不会去刷新缓冲区而直接调用到系统级的退出,所以上面的cout是打印不出来的。。。
//一般来说,cout输出到终端,一般是行缓冲,当然重定向到文件另当别论。。。
ci……
[/Quote]
我不知道vs2008的_exit是如何实现的,但是如果有条件,lz可以使用gcc试试,我手头也没有编译器,可能的话,我明天到公司看看。。。
bluewanderer 2010-11-28
  • 打赏
  • 举报
回复
可能linux下是stdin刷stdout。不知道MinGW调的是VC库还是用自己的库,不过手头也没有。VC下<<字符串就是调用putc,而putc很诡异地会直接判断是不是stdout或者stderr,如果是就直接跳过缓冲||| 搞不好这里还得有bug,要不就是我看差了。不过整体上,个人还是倾向于微软的不缓冲逻辑。
yiruirui0507 2010-11-28
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 hqin6 的回复:]
lz可以试试下面的代码:

int main()
{
int num;
cout<<"enter an interger:";
_exit(0);//----这里_exit函数不会去刷新缓冲区而直接调用到系统级的退出,所以上面的cout是打印不出来的。。。
//一般来说,cout输出到终端,一般是行缓冲,当然重定向到文件另当别论。。。
cin>>num;
cout<<endl;
……
[/Quote]

首先感谢回答,你的第一个我测试了,结果出乎意料:显示了上面那行!真的显示了,VS08!
加载更多回复(14)

64,677

社区成员

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

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