您的位置:首页 > 其它

fgets与gets的区别

2015-02-04 13:48 232 查看
首先看看他们各自的定义:

gets:从stdin流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中。换行符不作为读取串的内容,读取的换行符被转换为‘\0’空字符,并由此来结束字符串。

fgets:读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'),如果文件中的该行,不足bufsize个字符,则读完该行就结束。如若该行(包括最后一个换行符)的字符数超过bufsize-1,则fgets只返回一个不完整的行,但是,缓冲区总是以NULL字符结尾,对fgets的下一次调用会继续读该行

今天遇到的一个问题就是,他们二者对Enter键引入的换行符的处理。

练习用UDP 写一个简单的聊天程序,当客户端client发送 消息给服务端server时,server会将消息打印到窗口:

printf("%s --From %s\n",recvBuff,inet_ntoa(SockAddrClnt.sin_addr));

但测试中发现,格式不是想要的如图:



本应该是:你好--From 127.0.0.1

猜测应该是--之前加了个换行符。之前习惯于用gets,没出现过这种问题。于是调试一下,看看收到的字符串是怎么样的。



发现真的多了一个ascII为0x0A的字符,正是换行符!!

结论:fgets函数会读取键盘输入的换行符(Enter,我们每击打一下"Enter"键,向键盘缓冲区发去一个“回车”(\r),一个“换行"(\n),在这里\r被scanf()函数处理掉了),并在换行符后加上'\0'.

gets函数将读取到的换行符转换为‘\0',以此结束字符串。

解决方法:在用fgets读取后,对接收数组做下处理:

recvBuff[strlen(recvBuff)-1]='\0';作用就是将换行符换为‘\0.’





还有一个注意点就是:

gets函数可以无限读取,不会判断上限,所以程序员应该确保buffer的空间足够大,以便在执行读操作时不发生溢出。如果溢出,多出来的字符将被写入到堆栈中,这就覆盖了堆栈原先的内容,破坏一个或多个不相关变量的值。这个事实导致gets函数只适用于玩具程序,为了避免这种情况,我们可以用fgets(stdin)
(fgets实际上可以读取标准输入(即大多数情况下的键盘输入),具体参阅fgets词条)来替换gets()。在V7的手册(1979年)中说明:为了向后兼容,gets删除换行符,gets并不将换行符存入缓冲区

补充一下,getchar也会将换行符放在键盘缓冲区

getchar 由实现:#define getchar() getc(stdin)。getchar有一个int型的返回值.当程序调用getchar时.程序就等着用户按键.用户输入的字符被存放在键盘缓冲区.直到用户按回车为止(回车字符也放在缓冲区中).
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息