6.3.2 克服gets_s函数的缺陷
在C语言中函数gets_s是从stdin流中读取字符串的函数,此函数接受从键盘上输入的字符直到遇到Enter键时终止。函数gets_s的原型是:
char* gets(char *buff);
例如:
#include <stdio.h> int main(void) { charstr[30]; while(! str! = gets_s (str)); printf("%s\n", str); return 0; }
如果读取成功,gets_s函数的返回值是和str值相同的指针,否则返回空指针。
函数gets_s是一个危险的函数,原因是用户在键盘上输入的字符个数可能大于缓冲区的最大值,而函数gets_s并不对其检查。当用户在键盘上输入多个数据时,程序有可能会发生崩溃。解决方法是重写一个新的函数gets_s,原型是:
char* Gets(int maxlen)
这个函数可让程序员指定输入字符的最大个数,在函数中为字符分配存储空间,函数返回char*。
这个函数是针对动态数组而编写的,例如:
int main(void) { char*p; p=Gets(18); }
函数gets_s中的参数舍弃传入指针的原因是传入函数的指针可能不可靠,这样会造成程序崩溃,比如传入一个野指针。
另一个gets_s函数的原型是:
char* const Gets(char* const array, int maxlen);
这个函数针对固定长度的字符数组进行输入,例如:
int main(void) { charstr[20]; Gets(str,20); return 0; }
此时函数gets_s中的有一个参数是char* const类型,原因是它允许程序员修改这个类型指针所指向的内容,但不能修改指针本身。具体实现代码如下。
#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(void) { char s[8]; Gets(s,8); puts(s); fflush(stdin); //刷新输入缓冲区,这很重要,否则会影响下一个Gets函数 char*p=Gets(8); puts(p); return 0; }