一 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;
}
作者:wangzhicheng2013