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时.程序就等着用户按键.用户输入的字符被存放在键盘缓冲区中.直到用户按回车为止(回车字符也放在缓冲区中).
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时.程序就等着用户按键.用户输入的字符被存放在键盘缓冲区中.直到用户按回车为止(回车字符也放在缓冲区中).
相关文章推荐
- 区别 scanf gets fgets
- gets和fgets的区别.
- gets()、puts()和fgets()、fputs() 的区别。
- C经典 scanf 、gets 与fgets区别
- fgets和gets的区别
- scanf gets 和 fgets的区别
- gets和fgets的区别
- fgets和gets在各自使用情况下的一点区别
- scanf() & gets() & fgets() 读取字符串的区别
- fgets与gets的区别
- fgets和gets的区别
- fgets()和gets()的区别
- C语言中回车,换行,空字符与空格:fgets和gets在读取换行符的区别
- fgets()与gets()的区别
- fgets和gets的区别
- fgets()和gets()函数的区别
- C语言中getch、getche、fgetc、getc、getchar、fgets、gets之间的区别
- fgets、gets和scanf的区别
- 标准文件IO以及scanf fgets gets 以及printf sprintf fprintf的区别
- gets和fgets函数的区别