每当讨论 gets 函数时,大家不由自主地就会想起 1988 年的“互联网蠕虫”,它在 UNIX 操作系统的 finger 后台程序中使用一个 gets 调用作为它的攻击方式之一。很显然,对蠕虫病毒的实现来说, gets 函数的功劳不可小视。不仅如此,GCC 也不推荐使用gets和puts函数。

那么,究竟是什么原因导致 gets 函数这么不招人待见呢?

正确的语句是d (int)k%m28. 不能进行++和--运算的数据类型为d 指针b)整型c) 长整型d) 常量 name:29. putchar函数可以向终端输出一个d 整型变量表达式b)实型变量值 字符串d)字符或字符型变量值 30. printf函数中用到格式符%5s,其中数字5表示输出的字 符串占用5列。gets函数功能:从键盘上输入字符,直至接受到换行符或eof时停止,并将读取的结果存放在buffer指针所指向的字符数组中。这次我输入了zhang和回车换行,fgets函数依然是读取5个字符(len-1个),这时fgets()读入zhang,已经是五个字符了,所以回车换行并不会读入,最后fgets()添加字符串结束标志'\0',所以我们看到输出时,press any...并没有换行输出,而是和zhang在同一行。

该函数为在栈中分配size个字节的内存空间, 函数返回时会自动释放该空间. 成功返回指针, 失败返回null.。定义目录结构信息结构体dirent对象指针pdirent,之后通过一个while循环,该循环内通过调用readdir函数,以读取打开的目录对应的操作返回结果判断为条件。首先,next是一个指针,它指向一个函数,该函数返回另一个指针,该指针指向一个类型为char的常量指针,或者说next是一个指向函数的指针,该函数返回另一个指针,该指针指向一个只读的指向char的指针。

如果函数的调用者提供了一个指向堆栈的指针,并且 gets 函数读入的字符数量超过了缓冲区的空间(即发生溢出),gets 函数会将多出来的字符继续写入堆栈中,这样就覆盖了堆栈中原来的内容,破坏一个或多个不相关变量的值。如下面的示例代码所示:

int main(void)

{

char buffer[11];

gets(buffer);

printf("输出: %s\n",buffer);

return 0;

}示例代码的运行结果为:

aaa

输出: aaa

根据运行结果,当用户在键盘上输入的字符个数大于缓冲区 buffer 的最大界限时,gets 函数也不会对其进行任何检查,因此我们可以将恶意代码多出来的数据写入堆栈。由此可见,gets 函数是极其不安全的,可能成为病毒的入口,因为 gets 函数没有限制输入的字符串长度。所以我们应该使用 fgets 函数来替换 gets 函数,实际上这也是大多程序员所推荐的做法。

相对于 gets 函数,fgets 函数最大的改进就是能够读取指定大小的数据,从而避免 gets 函数从 stdin 接收字符串而不检查它所复制的缓冲区空间大小导致的缓存溢出问题。当然,fgets 函数主要是为文件 I/O 而设计的(注意,不能用 fgets 函数读取二进制文件,因为 fgets 函数会把二进制文件当成文本文件来处理,这势必会产生乱码等不必要的麻烦)。其中,fgets 函数的原型如下:

fgets函数功能:从文件指针stream中读取字符,存到以s为起始地址的空间里,知道读完n-1个字符,或者读完一行。函数说明 fgets()用来从参数stream所指的文件内读入字符并存到参数s所指的内存空间,直到出现换行字符、读到文件尾或是已读了size-1个字符为止,最后会加上null作为字符串结束。空语句和复合语句27413.3.2控制语句27513.3.3跳转语句27613.3.4关于分号的说明276习题13276第14单元函数28014.1函数参数28014.1.1现代c语言函数参数不能空28014.1.2c语言函数调用中的值结合28014.1.3指针类型参数28214.2函数定义与函数声明28914.2.1函数定义28914.2.2函数声明29014.3内联函数29114.3.1内联函数的概念29114.3.2c99的内联函数定义29114.3.3gcc的内联函数定义29214.3.4内联函数的限制292习题14292第15单元输入/输出29715.1格式化输出函数printf29715.1.1printf格式参数结构29715.1.2printf基本格式符29715.1.3长度修饰符29815.1.4域宽与精度说明29915.1.5前缀修饰符29915.2格式化输入函数scanf30115.2.1scanf指针参数30115.2.2scanf格式参数结构30215.2.3数值数据的输入控制30415.2.4scanf与输入缓冲区30515.2.5字符型数据的输入控制30615.2.6scanf的停止与返回30915.3c语言的文件操作31015.3.1文件及其分类31015.3.2file类型及其指针31215.3.3c语言文件操作的一般过程31315.3.4文件操作程序示例316习题15318附录324附录ac语言关键字324附录bc语言运算符的优先级和结合方向324附录c编译预处理命令325c.1宏定义325c.2文件包含326c.3条件编译326附录dc标准库头文件326附录ec语言常用标准库函数327e.1数学函数327e.2字符函数和字符串函数328e.3输入/输出函数329e.4动态内存分配函数331e.5退出程序函数331e.6数值转换函数331e.7时间和日期函数332参考文献333。

与 gets 函数不同的是,如果 fgets 函数读到换行符,就会把它存储到字符串中,而不是像 gets 函数那样丢弃它。即给定参数 n,fgets 函数只能读取 n-1 个字符(包括换行符)。如果有一行超过 n-1 个字符,那么 fgets 函数将返回一个不完整的行(只读取该行的前 n-1 个字符)。但是,缓冲区总是以 null('\0') 字符结尾,对 fgets 函数的下一次调用会继续读取该行fgets读取一行。

字符数组中一个元素只能存放一个字符,如 char a:表示定义了一个一维字符数组a,可存放5个字符,或存放最大长度为4的1个字符串(最后一个字符是字符串结束符‘\0’)。也就是说,后续的getchat()调用不会等待用户按键,而是直接读取缓冲区中的字符,直到缓冲区的字符读取完毕后,才等待用户按键。这里情况比较复杂的是scanf()函数,如果是scanf("%d",&a),它会忽略输入的空白符(换行,制表,空格)直到遇见非空白字符,再将其转换成整型存储在a中,注意,由于i/o缓冲,用来刷新输入缓冲的换行符还在等待被输入接受,此时能用getchar()捕获,但是在非空字符前面被忽略的空白符却因为被scanf()丢弃,已经不存在了。

最后,它还需要第 3 个参数来说明读取哪个文件。如果是从键盘上读入数据,可以使用 stdin 作为该参数,如下面的代码所示:

int main(void)

{

char buffer[11];

fgets(buffer,11,stdin);

printf("输出: %s\n",buffer);

return 0;

}对于上面的示例代码,如果输入的字符串小于或等于 10 个字符,那么程序将完整地输出结果;如果输入的字符串大于 10 个字符,那么程序将截断输入的字符串,最后只输出前 10 个字符。示例代码运行结果为:

aaaaaaaaaaaaaaaa

输出: aaaaaaaaaa

除此之外,C99 还提供了 fgets 函数的宽字符版本 fgetws 函数,其函数的一般原型如下面的代码所示:

该函数的功能与 fgets 函数一样。

本文来自电脑杂谈,转载请注明本文网址:

http://www.pc-fly.com/a/jisuanjixue/article-101477-1.html

c语言中gets与fgets,gets和fgets函数及其区别,C语言gets和fgets函数详解相关推荐

  1. int在c语言中的作用,C语言中int,Uint,uint16等有什么区别以及用处

    C语言中int,Uint,uint16等有什么区别以及用处.在C中,既然有了int,为什么还要有uint?特别是uint16,uint32等又有什么用?他们有什么区别?" --------- ...

  2. C语言中,#include的用法:#include 和 #include区别

    C语言中,#include的用法:#include "" 和 #include<>区别 采用 " ":依次搜索当前目录.包括/I编译开关的路 ...

  3. c语言char数组和short数组的区别,详解C语言中Char型指针数组与字符数组的区别

    详解C语言中Char型指针数组与字符数组的区别 详解C语言中Char型指针数组与字符数组的区别 1.char 类型的指针数组:每个元素都指向一个字符串,指向可以改变 char *name[3] = { ...

  4. Go语言中的fmt.Print, fmt.Printf, fmt.Println的区别和使用场景

    Go语言中的fmt.Print, fmt.Printf, fmt.Println的区别和使用场景 fmt 包的介绍 fmt.Print === 原样输出 fmt.Printf === 格式输出 fmt ...

  5. c语言中\0’ ,‘0’, “0” ,0的区别

     看来基础还是很重要的,基础不扎实就难以学好c语言,就别说写出高质量的c语言代码了.今天,我就被这个问题折磨的不行了,哈哈,不过现在终于明白了'\0' ,'0', "0" 之间的区 ...

  6. c语言中的long是什么字符类型,long long 在c语言中是什么类型

    "longlongint"在C语言中是64位长整型数据类型.longlong是属于int型,一般来讲,是longint型大小的两倍,int型的4倍. "longlongi ...

  7. C语言中exit(0) 、exit(1) 和return的区别

    C语言中的exit 文字描述 代码验证 return 表示返回 , 函数返回 exit 表示程序退出 exit(0) 表示正常退出,代码为1 exit(1) 表示异常退出,代码为1 文字描述 retu ...

  8. C语言中,printf、sprintf、fprintf之间的区别及用法举例

    目录 1. printf 2. sprintf 3. fprintf 在C语言中,sprintf.printf.fprintf都是用来输出字符串的函数,它们之间的主要区别在于输出的位置不同. 它们之间 ...

  9. 在c语言中,以r方式不能打开并不存在的文件,C语言文件选择题

    C语言文件选择题(答案在最后) 1.标准库函数fgets(s,n,f)的功能是 A) 从文件f中读取长度为n的字符串存入指针s所指的内存 B) 从文件f中读取长度不超过n-1的字符串存入指针s所指的内 ...

  10. Swift语言中class、struct、enum的联系与区别

    相同点 三者都可以拥有属性和方法(enum本身不能储存属性,但是可以储存在其关联信息中,可以有计算属性) 都可以拥有函数 class和struct可以拥有自己的构造器 不同点 类可以继承 类可以内省和 ...

最新文章

  1. Developerkit Link Develop Demo 环境配置指南
  2. mark一下总是记混的重定向与转发的区别
  3. python快速编程入门教程-终于懂得python快速编程入门教程
  4. bootstrap table教程--使用入门基本用法
  5. Vue + VueRouter + Vuex + Axios 抓取 GitHub 上的 Issues 来搭建个人博客站点
  6. PHP下实现两种ajax跨域的解决方案之jsonp
  7. 【问链财经-区块链基础知识系列】 第四十六课 区块链如何作用于医药行业
  8. 工厂Bean 的实现类getObject 方法创建Bean 实例对象
  9. 好久没发胡说八道的贴了,今天发一贴
  10. Maven项目启动时如何查找默认的显示页面
  11. 为什么35岁的C++依然能主导编程世界
  12. (转)令人无法理解的死锁案例分析
  13. linux 解压加密zip,linux 系统下 zip 的加密压缩与解压缩命令
  14. 大数据是什么 有哪些价值
  15. git 创建本地仓库,再关联远程创库
  16. 深度学习及机器学习整理--多谢各个网络大神
  17. js立即执行函数,jqueryReady和Onload执行顺序比较
  18. day09-商品规格管理
  19. three.js 物体轮廓高亮
  20. window电脑访问Android照片,解决JPEG照片在windows无法打开

热门文章

  1. 临沂中考计算机试题,初中信息技术教师基本功比赛测试题
  2. 问题描述给定n个矩阵:A1,A2,…,An,其中Ai与Ai+1是可乘的,i=1,2…,n-1。确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。
  3. C++:实现量化doublebarrier option双障碍期权 测试实例
  4. DELPHI定义的条件编译的全部说明
  5. 2023年软件设计师备考经验(附个人整理资料 全)
  6. [原创]科普_3G时代如何买手机
  7. yangguang-终于找到了可以在手机上玩的极品飞车游戏(J
  8. ffmpeg中常用的rgb格式转换为bmp图片格式
  9. 引用 Windows虚拟内存最小值太低,怎么办?
  10. 5G网络结构及Options