关于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)> 字符读写 ...
随机推荐
- UML视图(九)部署图
一.什么是部署图? 部署图对面向对象系统的物理方面建模,描写叙述系统执行时节点.构件实例及其对象的配置.主要用来在部署系统时涉及到的硬件(处理器和设备)进行建模. 二.部署图的组成元素? 部署图主要包 ...
- 高级进程间通信之基于STREAMS的管道
基于STREAMS的管道(简称STREAMS管道,STREAMS pipe)是一个双向(全双工)管道.单个STREAMS管道就能向父.子进程提供双向的数据流. 将http://www.cnblogs. ...
- 图片onerror(转)
<script type="text/javascript"> <!– function nofind(){ var img=event.srcElement; ...
- 小白日记43:kali渗透测试之Web渗透-SqlMap自动注入(一)-sqlmap参数详解TARGET
SqlMap自动注入(一) sqlmap是一款非常强大的开源sql自动化注入工具,可以用来检测和利用sql注入漏洞[动态页面中get/post参数.cookie.HTTP头].它由Python语言开发 ...
- Cannot start service SPUserCodeV4 on computer
Cannot start service SPUserCodeV4 on computer SharePoint2010 部署问题: 当Visual Studio 2010中尝试部署Sharepoin ...
- [Android]应用的前后台运行
在开发中,你是不是没有抽象一个出常用的类,那你可能要为你的懒惰付出很大的代价.要时刻记得自己的工具箱,不断往里面添加一些小小玩意.今天就给大家带来一个很有意思的例子.前后台运行!! 在Android开 ...
- Flex RPC错误整理 转
http://wenku.baidu.com/link?url=l2T80q4OXOIvUEmVn97XL-By9_GClgHMDmY5fuu-XSmQDqH56_AUa19pjbdA_SlwhFnu ...
- Sublime Text—安装
一.简介 市面上的编辑器纷繁复杂各有优点,好用的编辑器能让你工作事半功倍,先简单介绍下本文主角Sublime Text编辑器,下面简称Sublime. 1.可用于 Windows.Mac OS X 和 ...
- Https要点
http和https的区别 1.https协议需要到ca申请证书 2.http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议 3.http和https使用的是完全不同 ...
- Rust 学习 0
安装Rust 后,本地有文档: file:///usr/local/share/doc/rust/html/index.html file:///usr/local/share/doc/rust/ht ...