博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

谁能解决这个C语言问题?(转)

Posted on 2013-05-09 08:54  凤凰火舞  阅读(275)  评论(0编辑  收藏  举报

 

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     char buff[50];
 6     while (true)
 7     {
 8         scanf("%s", buff);
 9         printf("you inputed: %s\n", buff);
10     }
11     return 0;
12 }

问题描述

这段程序不停的向用户要求输入一些文字,当用户输入后紧接着就把这些文字显示出来。

这个程序是无限循环的,但是这并没有什么关系,因为每一次 scanf() 调用的时候,都会停下来等待用户输入。所以用户可以不慌不忙的输入一些东西,然后回车,程序就把这些东西给显示了出来。

这个程序很简单,没什么太大的用处。一眼看起来似乎也没什么稀奇的,即使不亲自编译运行,也能猜到大概运行起来大概是个什么样子——这是许多人第一眼的印象,可是如果考虑重定向输入流,这个程序就会出现一个致命的 bug,请按照下面的步骤来重现这一 bug:

1、把程序编译为 bug.exe

2、在 bug.exe 所在的目录下新建文本文件 break.txt,内容随便输入即可,例如 123,然后保存

3、在控制台下运行 bug.exe < break.txt

结果就会发现程序陷入了死循环。而且是毫无等待,不停刷屏的死循环。

请给出解决方案,使得即使是重定向了输入流,我们的程序也能正常工作——等待用户用键盘输入一些东西,然后优雅的将他们显示出来,然后再让用户输入,再显示,如此往复,就好象没有重定向输入流时所表现的那样。

提示一点点:

正常情况下,即没有重定向输入流的情况下,当 scanf() 尝试从输入缓冲中读取数据却发现无数据可读的时候,就会阻塞住,等待用户输入一些数据,然后再返回。可是当重定向输入流后,scanf() 的行为却变了——如果发现无数据可读,不会阻塞,会立刻返回一个 EOF(数字 -1)。

在开始解决问题之前请注意四点:

1、这个程序还存在其他的 bug,例如缓冲区溢出等,但不是本次关注的内容,因此请忽略

2、一种“解决办法”是去判断 scanf() 的返回值是否为 EOF,如果是则 break,这样虽然不会死循环,但是意义也不大,因为程序虽然不会死循环刷屏,但是也不能再从用户处获取数据,因此并没有真正解决问题。(问题的本质是弄清楚 scanf() 为什么不阻塞了,如何让它再阻塞)

3、这是一个开放性问题,即使你的结论是——不可能做到——也是可以的,关键是你要能够从理论和实践两方面进行验证。当然我们更希望听到结论是——可以做到。

4、可以借助 C 标准库之外的其他第三方库/函数来解决。(转载