关于函数那些事--C语言学习(1)

来源:互联网 发布:酒精漱口 知乎 编辑:程序博客网 时间:2024/05/29 06:58
大家学习C语言一般的学校都会选择windows下的VC++6.0作为开发环境吧。VC本身确实很强大,在十几年前来看的话,这里不展开吐槽了。只是想说VC本身使用并不支持C99,更不用说C11了。而落后必然导致一些问题。在此只讲一个不安全的函数gets()及其解决方法

tips:关于C99 啥的可以看一下ANSI C
我们先来看一下函数原型

char *gets(char *string);

gets()函数从流中读取字符串,直到出现换行符或读到文件尾为止,最后加上NULL作为字符串结束。所读取的字符串暂存在给定的参数string中。若成功则返回string的指针,否则返回NULL。

  初学c语言时觉得gets真的很好用,与scanf相比可以输入在字符串中输入空格。最近使用linux下的vim却发现gets函数没有了,而且这个函数很危险。  从上面的说明我们可以看到,直到出现换行符或文件尾才结束读取,那么如果我输入了一个长长的字符串呢?

结果是很可怕的。。。

  你输入的字符串将一直被写入缓存区,超出了原本的存储空间,覆盖其他的数据,造成程序崩溃,被其他人将恶意代码写入,甚至让别人能取得权限等等。。  所以在C11中,gets函数被删除了。

那么用什么替代gets呢?

答案是fgets

char *fgets(char *buf, int bufsize, FILE *stream);
函数成功将返回buf,失败或读到文件结尾返回NULL.我们只需要将原本是文件指针的地方改成stdin. buf是写入的数组名,bufsize为写入的字符数。注意fgets最多只会读入bufsize-1个字符,默认最后一位为NULL,这也是保证了不会写入过多的字符。

例子

#include<stdio.h>#include<string.h>#include<stdlib.h>int main(void){    char str[10];    fgets(str,10,stdin);    fputs(str,stdout);    printf("\n");}

3种输入情况

  1. 函数参数为10,当我们输入超过了10个字符,由输出可知,str数组中存放了kangkangh 9个字符加一个NULL
  2. 当输入恰好为参数buf-1个时,str数组内容和第1种一样。
  3. 当输入不足9时str数组在NULL之前多存放了一个/n(在gets函数中这个输入的换行符会被转换成NULL存入数组)。

    小彩蛋

    大家注意到了吗? fputs函数默认不换行,而puts函数则不同

    总结

    gets函数可能导致及其危险的后果,所以还是用fgets来替代它吧。

    后记

    对于gets函数,微软有一个‘安全’的替代函数gets_s,可以在VS上使用,但可移植性太差,读者若感兴趣可自行搜索了解,本文不多介绍。

0 0