fgets函数自己的理解

来源:互联网 发布:mac里vm文件夹 编辑:程序博客网 时间:2024/04/30 00:51

gets函数容易发生越界错误,已经看到好多书、文章提到这一点。在写输入时就采用fgets函数,发现函数虽小,没理解透还是问题多多。

char  *fgets(char *s, int n, FILE *stream);

问题1:FILE *stream 参数误用STDIN_FILENO

代码:

将输入打印出来,执行这个程序:


分析:STDIN_FILENO是头文件<unistd.h>中定义的宏,数据类型是int,属于系统调用接口中标准输入的文件描述符,是没有缓存的I/O。

    fgets函数中第三个参数类型为FILE *,FILE是一个数据结构用于访问一个流。stdin,stdout,stderr都是指向FILE结构的指针。

修改代码fgets(s1,10,stdin);再运行:


输入fuck,输出fuck。


问题2:输入字符串长度小于参数n

代码:


检查输入的字符串如果为fuck则打印输出,如果不是则输出bug。执行:


输入fuck,结果打印显示bug。

分析:fgets函数将输入的fuck\n输入到了s1数组中,if做比较时因而出错。这里就提醒了对fgets函数的使用需要对误输入的“\n”做处理。

修改代码


将输入字符串的\n替换为\0,在比较输出。执行结果:


输入fuck,打印出fuck。


问题3:输入字符串长度超过n的大小

利用上面的代码,将if判断部分去掉,直接将输入打印输出。输入一段很长的字符串,注意此时s1数组长为10。执行:


输入了一串很长的字符,fgets函数值去了输入的9个字符,并将最后一个字符修改为\0,s1[8]='\0',s1[9]='\0'。并且发现过长的输入虽然被截取走前9个字符,但是余下的字符串直接作为下一次的命令执行了。fgets函数相对于gets函数的优点就是防止越界,具有更高的安全性,就是体现在这里。只取数据存储内存大小的数据,超过则丢弃。

setbuf(stdin,NULL)函数将标准输入设置为没有缓冲区的I/O操作,因而会出现上面将多余的字符串也打印出来的结果。但是在Ubuntu中缺可以用setbuf(stdin,NULL);来清除输入缓存数据,做一个测试代码:


输入字符串到s1,输入一个整数给a,并分别打印输出。在输入完字符串时,执行setbuf语句,观察对输入整型数据有没有影响。执行:

输入一个长字符串后发现对紧接着的整型数据输入并没有影响,如果去掉setbuf语句则会出现:

输入字符串中多余的部分直接给了整型数据的输入,出现了乱码。

OK,今天遇到的问题全部记录下来了。大笑

0 0
原创粉丝点击