关于fputs和fgets的几个细节
C语言中两个标准IO fputs和fgets都是针对行来进行数据的读取的!这里关于这两个IO函数我有几个小细节想在这里和大家分享一下,希望能够对大家产生帮助!
首先贴上这两个函数的函数声明,下面以这两个函数声明为基础进行讨论:


我用于调试的代码如下:
/* 本程序的输入为nihaoa,然后通过gdb调试来查看fputs的缓冲区内的内容
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h> #define MAXLINE 4 int main(int argc,char *argv[])
{
char buffer[MAXLINE];
memset(buffer,,MAXLINE);
char buffer_o[BUFSIZ];
memset(buffer_o,,BUFSIZ); setbuf(stdout,buffer_o); while(NULL != fgets(buffer,MAXLINE,stdin))
{
if(EOF == fputs(buffer,stdout))
{
printf("[fputs]: %s",strerror(errno));
exit(EXIT_FAILURE);
}
} if(ferror(stdin)) //检查上面循环停止是否是因为出错
{
printf("[fgets]: %s",strerror(errno));
exit(EXIT_FAILURE);
} buffer_o[] = 'k';
buffer_o[] = 'j';
/* 这里我把fputs的缓冲区的内容调整了一下,最后一个换行字符变成了k,换行字符的后一个变成了j,但是fputs输
* 出的时候还是输出了到k的内容,后面那个j并没有输出。所以fputs输出的时候并不是根据字符的最后一个'\0'来确
* 定的,而是在这个程序内有个计数器,来计量一共输入了多少个字符,然后再来输出的。
*/ return ;
}
首先说第一个问题,fgets每回从其缓冲区内读的数据的长度为SIZE-1个字节,然后它会自动在字符串末尾添加一个'\0'符号!而fgets将字符串存入其缓冲区的时候,会自动忽略末尾的'\0'符号!如下图所示:

就比如上面的那个程序!字符数组buffer用来充当这个程序的缓冲区!而那个buffer_o我通过setbuf函数来让它变成了标准输出的缓冲区!为了便于区分,我把这两个数组的数据初始化全部设置为1.
举个例子,比如我在上面那个程序的19行和21行设置两个个断点!然后运行查看buffer的内存!
首先是第19行的,此时buffer的内存全部都是1:

然后运行一句,我输入的数据是nihaoa<CR>,由于buffer的内容不够大,所有它只会读size-1也就是3个字节的内容,最后一个字节填充为0,如下图所示:

上面这个就说明了关于fgets的内容,它只从它的缓冲区中读取size-1个字节,然后在字符串的尾部加上一个0;
接下来我们接着调试,继续来向下运行一步,其结果如下图所示:

这里这个buffer_o是stdout的缓冲区,此时它里面只有3个字节的内容,这正好说明了关于fputs的部分,从目标内存中读取字符串,并且忽略掉字符串尾部的'\0'。
接着我们再来说第二个问题,那就是fputs程序内部应该有一个计数器,用来统计stdout的缓冲区中一共有多少个字符,fputs输出的时候就是根据这个计数器来输出!我们还是以上面那段代码为例,这回我们在34行和40行设置一个断点。再来看buffer_o这片内存中的内容!如下图所示:

这回我的输入还是nihaoa<CR>,这回stdout的缓冲区中放的内容就是nihaoa<CR>的ASCII码了!然后我把那个回车和回车的下一个的ASCII码改一下,如下图所示:

回车字符变成了k,它的下一个变成了j。然后我们再来查看输出的结果!
由于gdb自动添加了一个换行符,所以我就以普通方式运行查看了!如下图所示:

最后的输入是nihaoak,并没有多,这里就说明fgets的输出是根据它的那个计数器来的!
关于fputs和fgets的几个细节的更多相关文章
- fputs与fgets
1. fputs 函数名: fputs 功 能: 送一个字符到一个流中 用 法: int fputs(char *string, FILE *stream); 说明: fputs是一 ...
- 标准 IO fgets与fputs 对文件的操作
char *fgets(char *s, int size, FILE *stream); int fputs(const char *s, FILE *stream); 使用fgets从流中读取 ...
- C语言 文件操作8--fputs()和fgets()
//fputs()和fgets() #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> # ...
- 文件字符读写函数fscanf()和 fgets() 比较
一. 文件格式化读入函数 fscanf() int fscanf(文件指针,格式化字符串,输入列表); 返回值: 整形,输入列表中定义字符串的个数. 1, 例如读取字符串: char str1[ ...
- 第五章 标准I/O
5.1 引言 本章说明标准 I/O 库.因为不仅在 UNIX 上,而且在很多操作系统上都实现了此库,所以它由 ISO C 标准说明. 标准 I/O 库处理很多细节,例如缓冲区分配,以优化长度执行 I/ ...
- 标准IO函数以及基本知识点总结
什么是标准IO呢?有哪些特点? 标准IO是标准c库提供的对文件操作的函数接口.他的特点是:1 带缓存,2 大部分都调用系统接口函数实现.(c库就是一种实现好的函数接口,作用是屏蔽下层细节.提供上层接口 ...
- [apue] 标准 I/O 库那些事儿
前言 标准 IO 库自 1975 年诞生以来,至今接近 50 年了,令人惊讶的是,这期间只对它做了非常小的修改.除了耳熟能详的 printf/scanf,回过头来对它做个全方位的审视,看看到底优秀在哪 ...
- c语言之I/O函数
c语言中常用的I/O函数 最常用的字符串的标准I/O函数有getchar().putchar().gets().puts().scanf().printf().fputs().fgets().getc ...
- C语言函数的读写
文件打开关闭函数:fopen()和fclose() <FILE *fopen(char *filename, char *mode)| int fclose(FILE *fp)> 字符读写 ...
随机推荐
- MHA手动切换 原创2 (主参与复制)
monitor 执行下面命令后, --orig_master_is_new_slave :原主变为新从,即server1变成了slave1的从.slave2跟据app1.conf中配制也变成了slav ...
- LXNetwork – 基于AF3.0封装的iOS网络请求库
本框架实现思路与YTKNetwork和RTNetworking类似,相当于一个简单版,把每一个网络请求封装成对象.使用LXNetwork,你的每一个请求都需要继承LXBaseRequest类,通过覆盖 ...
- Lexia3 Citroen/Peugeot Diagnostic tool install instruction
We knew that Lexia-3 is a professional Citroen and Peugeot diagnostic interface, it’s both easy-usin ...
- 为Google Reader守夜。。。
Google的阅读器快要关闭了... 立刻截图留恋呢,以后就没机会了. 唉,真是令人惋惜. 虽然我接触Google Reader还不到一年,但是我已经习惯当连上WiFi时马上更新一下手机上的gRead ...
- PureCSS框架
http://www.tuicool.com/articles/iyiI32 Pure中的主要组件包括: 一个响应式网格,可根据需求定制. 一个基于 Normalize.css 的基础库,用于修复跨浏 ...
- Inaccurate values for “Currently allocated space” and “Available free space” in the Shrink File dialog for TEMPDB only
转载自:http://blogs.msdn.com/b/ialonso/archive/2012/10/08/inaccurate-values-for-currently-allocated-spa ...
- MySQL Index Condition Pushdown(ICP) 优化
本文是作者留下的一个坑,他去上茅坑了.茅坑是谁?你猜.
- CSS的总结(选择器,伪类等...)
关于组合选择器可参考:http://www.cnblogs.com/starof/p/4453458.html 主要内容 CSS概述 CSS和HTML结合的四种方式 CSS样式优先级和代码规范 CSS ...
- Web系统大规模并发----电商秒杀与抢购
原文链接请参见:http://uule.iteye.com/blog/2186786
- hdu 2665 划分树
思路:裸的划分树 #include<iostream> #include<algorithm> #include<cstring> #include<cstd ...