setbuf

来源:互联网 发布:淘宝怎么找小二介入 编辑:程序博客网 时间:2024/06/05 21:50
setbuf是linux中的C函数,主要用于打开和关闭缓冲机制。
函数名: setbuf
功 能: 把缓冲区与流相联
用 法: void setbuf(FILE *steam, char *buf);[1]
说明:setbuf函数具有打开和关闭缓冲机制。为了带缓冲进行I/O,参数buf必须指向一个长度为BUFSIZ(定义在stdio.h头文件中)的缓冲区。通常在此之后该流就是全缓冲的,但是如果该流与一个终端设备相关,那么某些系统也可以将其设置为行缓冲。为了关闭缓冲,可以将buf参数设置为NULL。
程序例:
#include <stdio.h>
char outbuf[50];
int main(void)
{
/* 将outbuf与stdout输出流相连接 */
setbuf(stdout,outbuf);
/* 向stdout中放入一些字符串 */
puts("This is a test of buffered output.");
puts("This output will go into outbuf");
puts("and won't appear until the buffer");
puts("fills up or we flush the stream.\n");
/* 以下是outbuf中的内容 */
puts(outbuf);
/*刷新流*/
fflush(stdout);
return 0;
}

程序输出有两种方式:一种是即时处理方式,另一种是先暂存起来,然后再大块写入的方式,前者往往造成较高的系统负担。因此,c语言实现通常都允许程序员进行实际的写操作之前控制产生的输出数据量。

这种控制能力一般是通过库函数setbuf实现的。如果buf是一个大小适当的字符数组,那么:

setbuf(stdout,buf);

语句将通知输入/输出库,所有写入到stdout的输出都应该使用buf作为输出缓冲区,直到buf缓冲区被填满或者程序员直接调用fflush(译注:对于由写操作打开的文件,调用fflush将导致输出缓冲区的内容被实际地写入该文件),buf缓冲区中的内容才实际写入到stdout中。缓冲区的大小由系统头文件<stdio.h>中的BUFSIZ定义。

下面的程序的作用是把标准输入的内容复制到标准输出中,演示了setbuf库函数最显而易见的用法:

#include <stdio.h>

main()

{

int c;

char buf[BUFSIZ];

setbuf(stdout, buf);

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

        putchar(c);

}

    遗憾的是,这个程序是错误的,仅仅是因为一个细微的原因。程序中对库函数setbuf的调用,通知了输入/输出库所有字符的标准输出应该首先缓存在buf中。要找到问题出自何处,我们不妨思考一下buf缓冲区最后一次被清空是在什么时候?答案是在main函数结束之后,作为程序交回控制给操作系统之前C运行时库所必须进行的清理工作的一部分。但是,在此之前buf字符数组已经被释放!

    要避免这种类型的错误有两种办法。第一种办法是让缓冲数组成为静态数组,既可以直接显式声明buf为静态:

static char buf[BUFSIZ];

也可以把buf声明完全移到main函数之外。第二种办法是动态分配缓冲区,在程序中并不主动释放分配的缓冲区(译注:山于缓冲区是动态分配的,所以main函数结束时并不会释放该缓冲区,这样C运行时库进行清理工作时就不会发生缓冲区已释放的情况):

char *malloc();

setbuf(stdout,malloc(BUFSIZ));

    如果读者关心一些编程“小技巧”,也许会注意到这里其实并不需要检查malloc函数调用是否成功。如果malloc函数调用失败,将返回一个null指针。setbuf函数的第二个参数取值可以为null,此时标准输出不需要进行缓冲。这种情况下,程序仍然能够工作,只不过速度较慢而已。

遇到 The input is ended up with the end of file.就使用while(scanf("%d%d",&a,&b)!=EOF)这句话!具体操作是ctrl+z 结束while循环
本人在centos上试过是没有问题的 ,其他的不知道
原创粉丝点击