克服C语言gets函数缺陷的方法初探

克服C语言gets函数缺陷的方法初探

 

一 gets函数简介

gets函数是C语言用于从stdin流中读取字符串的函数。gets函数接收用户从键盘上输入的字符直到遇到回车时终止。原型是:

char* gets(char *buff);

举例:

#include <stdio.h>

int main()

{

      charstr[30];

      while(!str!= gets(str));

      printf(“%s\n”,str);

      return 0;

}

如果读取成功,gets函数返回值是和str的值相同的指针,否则,返回空指针。

二 gets函数的漏洞

gets函数是个危险的函数,原因是用户在键盘上输入的字符个数可能大于buf的最大界限,而gets函数并不对其检查。如在上例中,如果用户在键盘上输入1111111111111111…………….输入1的个数大于30,这时会造成程序崩溃。

三 gets函数漏洞的解决方案

我们可以重写一个新的函数Gets

原型是char* Gets(int maxlen)

这个函数让程序员指定一个最多输入字符的个数,在函数中为字符分配存储空间,函数返回char*

这个函数是针对动态数组而做的,如

int main()

{

      char*p;

  p=Gets(18);

}

Gets函数的参数之所以舍弃了传入的指针,是因为传入函数的指针可能不可靠,会造成程序崩溃,比如传入一个野指针。

另一个Gets函数原型是

char* const Gets(char* const array,int maxlen);

这个函数针对固定长度字符数组的输入,如

int main()

{

      charstr[20];

   Gets(str,20);

      return 0;

}

此时Gets函数参数之一之所以是char* const类型,是因为我们容许程序员修改这个类型指针所指向的内容,而不能修改指针本身,这和char str[30]中的str[0]=’1’,但不能str++效果一样。

具体实现代码如下:

#include <string.h>

#include <stdio.h>

#include <conio.h>  

#include <stdlib.h> 

#include <io.h>

char* Gets(int maxlen)

//最多从键盘上读入maxlen个字符,返回字符串指针类型

{

      int i;

      staticchar* str;

      char c;

      str=(char*)malloc(sizeof(char)*maxlen);

      if(!str)

      {

           perror("memeoryallocation error!\n");

           return0;

      }

      else

      {

           for(i=0;i<maxlen;i++)

           {

                 c=getchar();

                 if(c!='\n')str[i]=c;

                 elsebreak;

           }

           str[i]='\0';

           returnstr;

      }

}

 

char* const Gets(char* const array,int maxlen)

{

      int i;

      char c;

      for(i=0;i<maxlen;i++)

      {

           c=getchar();

           if(c!='\n')array[i]=c;

           elsebreak;

      }

      array[i]='\0';

      returnarray;

}

 

int main()

{

      char s[8];

      Gets(s,8);

      puts(s);

fflush(stdin); //刷新输入缓冲区,很重要,否则会影响下一个Gets函数

   char*p=Gets(8);

      puts(p);

      return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值