1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > c语言中gets与fgets gets和fgets函数及其区别 C语言gets和fgets函数详解

c语言中gets与fgets gets和fgets函数及其区别 C语言gets和fgets函数详解

时间:2018-06-20 04:22:59

相关推荐

c语言中gets与fgets gets和fgets函数及其区别 C语言gets和fgets函数详解

每当讨论 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-/a/jisuanjixue/article-101477-1.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。