对fgets的理解
gets()函数
因为用gets函数输入数组时,只知道数组开始处,不知道数组有多少个元素,输入字符过长,会导致缓冲区溢出,多余字符可能占用未使用的内存,也可能擦掉程序中的其他数据,后续用fgets函数代替。
fgets函数
一小段代码举例:
char words[stlen];
fgets(words,,stdin);
fputs (words,stdout);
puts(words);
(1) fgets函数一次读入10 - 1个字符,如果少于这个字符数数按下回车
例如输入apple pie 则会将apple pie\n\0储存在数组中
随后的fputs打印时不添加\n
而puts打印会添加\n,结果会空一行
(2) 一次读入超过10 - 1个字符则会在读取apple pie后加\0储存在数组中
打印时因为没有\n 函数fputs之后没有换行,紧接着puts打印
fgets()函数读到文件结尾会返回一个空指针,代码可用0代替,或者用NULL //因为暂时不常见在此不做介绍
在11.8中
# include<stdio.h>
# define stlen
int main(void)
{
char words[stlen];
while(fgets(words,stlen,stdin) != NULL&&words[] != '\n')//不断循环把stlen-1字符放在数组中加\0,直到最后结尾为\n\0,
fputs(words,stdout);
puts("done."); return ;
}
输入字符长度超过 10-1 时仍会全部打印,因为输入缓冲区的原因,输入aaaaaaaaabbbbbbbbbccccccccc,字符串会在缓冲区暂时保存,第一次while会将aaaaaaaaa输出但没有换行,
第二次时bbbbbbbbb,最后的c结束时会将ccccccccc\n\0储存打印时会换行。
储存换行符有好处也有坏处,想去除换行符,可以在已知的字符串中查找换行符,
while (words[i] != '\n')
i++;
word[i] = '\0';
如果仍有字符串留在输入行就用
while(getchar() != '\n')//读取但不储存输入,包括\n
continue;
这样可以清除缓冲区,超过设定长度会将后面的清除,只打印设定长度字符串。
# include<stdio.h>
# define stlen
int main(void)
{
char words[stlen];
int i;
while(fgets(words,stlen,stdin) != NULL&&words[] != '\n')
{
i = ;
while(words[i] != '\n'&&words[i] != '\0')
i++;
if(words[i] == '\n')
words[i] == '\0';
else //也就是words[0] == '\0'时
while(getchar() != '\n')
continue; puts(words); }
return ;
}
上述代码,若输入apple 则输出apple
若输入aaaaaaaaabbbbbbb 则输出aaaaaaaaa 因为在输入后缓冲区是aaaaaaaaabbbbbbb,读取规定字符数将aaaaaaaaa\0放在words中,后续代码检测到\0
因为getchar()缓冲区的字符b依次被读取并被丢弃,知道读取到换行符\n,输出words // \n 也被丢弃。
对fgets的理解的更多相关文章
- 通过编写c语言程序,运行时实现打印另一个程序的源代码和行号
2017年6月1日程序编写说明: 1.实现行号的打印,实现代码的读取和输出,理解主函数中的参数含义. 2.对fgets函数理解不够 3.对return(1); return 0的含义理解不够 4.未实 ...
- 深入理解C语言
语言只是一种工具,任何语言之间都是相通的,一通则百通,关键是要理解语言背后的思想,理解其思想,任何语言,拿来用就行了.语言没有好坏之分,任何语言既然存在自然有它存在的价值. 在一个到处是OOP的年代, ...
- C安全编码--整数理解
建议和规则 建议: 理解编译器所使用的数据模型 使用rsize_t或size_t类型表示所有表示对象长度的整数值 理解整数转换规则 使用安全的整数库 对来自不信任来源的整数值实行限制 如果输入函数无法 ...
- 理解Socket编程【转载】
“一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. ——有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览 ...
- 对于linux下system()函数的深度理解(整理)
原谅: http://blog.sina.com.cn/s/blog_8043547601017qk0.html 这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同 ...
- 转:对于linux下system()函数的深度理解(整理)
这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数中调用的命令也都一切正常.就没理这个bug,以为 ...
- 深入理解计算机系统_3e 第八章家庭作业 CS:APP3e chapter 8 homework
8.9 关于并行的定义我之前写过一篇文章,参考: 并发与并行的区别 The differences between Concurrency and Parallel +---------------- ...
- PHP性能优化利器:生成器 yield理解
如果是做Python或者其他语言的小伙伴,对于生成器应该不陌生.但很多PHP开发者或许都不知道生成器这个功能,可能是因为生成器是PHP 5.5.0才引入的功能,也可以是生成器作用不是很明显.但是,生成 ...
- PHP 进阶之路 - 深入理解 FastCGI 协议以及在 PHP 中的实现
在讨论 FastCGI 之前,不得不说传统的 CGI 的工作原理,同时应该大概了解 CGI 1.1 协议 传统 CGI 工作原理分析 客户端访问某个 URL 地址之后,通过 GET/POST/PUT ...
随机推荐
- 【zz】史上最全设计模式导学目录(完整版)
2012年-2013年,Sunny在CSDN技术博客中陆续发表了100多篇与设计模式学习相关的文章,涵盖了七个面向对象设计原则和24个设计模式(23个GoF设计模式 + 简单工厂模式),为了方便大家 ...
- 【转】[C++]实现委托模型
原文地址:http://www.cnblogs.com/zplutor/archive/2011/09/17/2179756.html 我对.Net的委托模型印象很深刻,使用委托,可以快速实现观察者模 ...
- AngularJs学习笔记--Understanding the Controller Component
原版地址:http://docs.angularjs.org/guide/dev_guide.mvc.understanding_model 在angular中,controller是一个javasc ...
- 对HandlerExecutionChain类的理解分析
HandlerExecutionChain类比较简单,好理解. ==================================================================== ...
- Failed to read candidate component错误
<context:component-scan base-package="com.spdb"/> <mvc:annotation-driven/> 加上该 ...
- springmvc(5)拦截器
1.什么是拦截器 是指通过统一的拦截从浏览器发送到服务器的请求来完成相应服务增强 2.拦截器的基本原理 可以通过配置过滤器解决乱码问题 和过滤器非常相似 3.搭建工程 注意jar包 此时的工程是完成后 ...
- HDU 2082 找单词 (普通型 数量有限 母函数)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2082 找单词 Time Limit: 1000/1000 MS (Java/Others) Me ...
- phpstudy 出现You don't have permission to access / on this server.
You don't have permission to access / on this server. 去掉vhost文件中的Options FollowSymLinks ExecCGI 第一次发 ...
- 基于uIP和uC/OS-II嵌入式网络开发
基于uIP和uC/OS-II嵌入式网络开发 ——uIP主动发送数据分析 摘要:uIP协议栈简单易用,可以为16位单片机或者是更低级的处理器使用,占用的资源很少,相关移植网上有详细介绍,本文主要讨论uI ...
- 基于jQuery+JSON的省市县 二级 三级 联动效果
省市区联动下拉效果在WEB中应用非常广泛,尤其在一些会员信息系统.电商网站最为常见.开发者一般使用Ajax实现无刷新下拉联动.本文将讲述,利用jQuery插件,通过读取JSON数据,实现无刷新动态下拉 ...