plain-C stdin缓冲垃圾和换行符

时间:2015-02-26 14:16:36

标签: c unix stdin

我有一个关于stdin缓冲区内容检查的问题。

这条备受赞誉的代码:

int c; while((c = getchar()) != '\n' && c != EOF);

有效处理丢弃stdin-buffer垃圾,以防发现垃圾。如果缓冲区为空,程序执行将不会超过它。

有没有办法检查stdin缓冲区中是否有垃圾(无论是因为用户错误,提前输入还是其中任何一个原因),并执行" fflush-replacement线"仅在发现垃圾的情况下从上面开始?

我更喜欢以编程方式将其全部保存在标准C的纯UNIX风格中,而不必使用特殊的解析工具,没有yacc,bison,python,ruby,shell脚本等,没有Windows API ,拜托。

提前致谢!

更新

我希望这个例子能说明我的问题:

//...
//this line should make sure stdin buffer is free from accidentally typed content
int c; while (( c = getchar()) != '\n' && c != EOF);

//this line won't show in case buffer is already clean
printf("Please enter an arbitrary number of float or symbolic values:\n");

//this line should read the real input user is being asked for
char* p = fgets(text, TEXT_SIZE, stdin);
if(p != NULL)
parse_and_process(text);
//...

没有意外输入时会发生问题。 "垃圾"在这里被认为是 printf()提示符出现时可能留在缓冲区中的任何内容。如果缓冲区已经清洁,有没有办法绕过第一行?

2 个答案:

答案 0 :(得分:0)

  

这条备受赞誉的代码:

int c; while((c = getchar()) != '\n' && c != EOF);
     

有效地处理   丢弃stdin-buffer垃圾

没有。这只是读取字符,直到找到换行符或达到EOF。我不知道你在说什么垃圾。

因此,通过执行此操作,您将使用stdin缓冲区中保留的换行符。这是刷新缓冲区的方法之一。

答案 1 :(得分:0)

编辑 以回复OP评论。

您需要指定什么是垃圾。只有这样,您(或其他任何人)才能确定哪些输入有效。

确定后,您可以编写一个例程,静静地使用 garbage 类别的用户输入,直到检测到某些非垃圾输入。

Windows(不是Unix)上的C编程中使用的 conio.h 标头包含控制台输入/输出的功能。 conio.h的一些最常用的函数是clrscrgetchgetchekbhit等。

以下是来自 here 的示例,演示了如何运行一个消耗输入的循环,直到非垃圾出现通过键盘...(在这种情况下,它被编写为使用转义键,使用改编的conio函数,但你可以根据你的目的进行调整)

   do
   {
      ch = _getch();
      ch = toupper( ch );

      if (ch != 27) {
         _cputs( "CHARACTER: " );
         _putch( ch );
         _putch( '\r' );    // Carriage return
         _putch( '\n' );    // Line feed
      }

   } while( ch != 27 ); 

原帖
这不回答 有没有办法检查stdin-buffer 中是否有垃圾,但它解决了如何确定它是明确...
添加一行 以向用户说明如何开始,并且由于您的原始代码,它将导致清除任何垃圾的缓冲区,或指示用户输入其他值之前的非预期输入 ......:...

    ...
    printf("hit <return> to begin");
    while ( (c = getchar()) != '\n' && c != EOF );
    printf("Please enter an arbitrary number of float or symbolic values:\n");    
    ...