【问题标题】:while(getchar() != multiple arguments)而(getchar()!=多个参数)
【发布时间】:2011-11-06 13:16:40
【问题描述】:

如何使用 getchar 作为 while 循环的条件,并在 (c=getchar()) = EOF 或 '\n' 或 '\0' 时终止。

我试过了:

int c=0;
while((c=getchar()) != EOF || '\n' || '\0'){
putchar();
}

这不起作用,如果我输入:WEATHER(+enter)。它没有终止循环。

我怎样才能做到这一点?

启发我

【问题讨论】:

标签: c while-loop getchar


【解决方案1】:

你可以这样使用:

int c = 0;
while((c=getchar()) != EOF) {
  if ((c == 0) || (c == '\n'))
    break;
  putchar(c);
}

【讨论】:

    【解决方案2】:
    while ((c = getchar()) != EOF && c != '\n' && c != '\0')
    {
      // loop body
    }
    

    这是因为 && 运算符 a) 总是首先计算 LHS 表达式,并且 b) 引入了一个序列点,因此 LHS 表达式中的任何副作用(例如将 getchar 的结果分配给 c ) 将在计算 RHS 表达式之前应用。

    【讨论】:

      【解决方案3】:

      我认为这应该可行:

      int c;
      while( (c=getchar()) != EOF && c!='\n' && c!='\0') {
          putchar();
      }
      

      但这样做可能会更好:

      int c=getchar();
      while( c != EOF && c!='\n' && c!='\0'){
          putchar();
          c=getchar();
      }
      

      【讨论】:

      • 第二个肯定更好。避免在条件中赋值,因为 = 和 == 很容易输入错误,维护中的意图可能不明确。
      【解决方案4】:

      遗憾的是,您需要将其分解为多个语句。您正在尝试执行多个事物的逻辑或,并且给定“真”是“任何非零”,并且字符只是数字,其中大部分是非零的,您基本上是在说“而 c 不是 EOF,或 TRUE 或 TRUE”。

      我不完全确定 C 规范,但重写语句如下可能有效:

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

      虽然根据评估顺序,这可能是未定义的,而且看起来很混乱。

      更好的解决方案是将“c=getchar()”移到其他地方,然后检查 while 标头中 C 的值。这确实意味着您必须将“c=getchar()”都移到循环外以及 while 循环体的底部。

      【讨论】:

      • 由于操作顺序,它不是未定义的;由于短路,子表达式保证按顺序发生。
      【解决方案5】:

      考虑您的代码,例如

      while (intint((int []){ EOF, '\n', 0 }, c=getchar(), 3) ...
      

      其中intint 是您编写的函数,类似于memchr,但需要一个整数数组。 :-)

      这个答案是半个笑话,因为其他答案已经很好地解决了这个问题,但关键是经常用正确的接口定义正确的函数可以让你的代码更简单。

      【讨论】:

        【解决方案6】:

        它不起作用,因为EOF || '\n' || '\0' 是一个布尔表达式,它总是会计算为true,所以条件归结为if( c != true ),如果c 为nul,则只有true,getchar() 不会正常返回。

        条件中的赋值总是不明智的,一些编译器会发出警告,除非赋值本身包含在括号中。这是为了防止意外使用 =,而更常见的 == 是在某种情况下使用的。

        在 C 中,即使每个都测试同一个变量,你也必须有单独的布尔表达式:

        int c = getchar() ;
        if( c != EOF && c != '\n' && c != '\0' )
            ...
        

        【讨论】:

          【解决方案7】:

          一个相当大但非常个性化的解决方案可能是:

          #include <stdarg.h>
          #define END_INPUT -12332 // not likely to be returned from getchar()...
          int is_any(int c, ...)
          {
              va_list ap;
              va_start(ap, c);
              int ret = 0;
              while (ret == 0) {
                  int a = va_arg(ap, int);
                  if (a == END_INPUT) break; // End of inputs - not any of the given ones
                  if (c == a) ret = 1; // will result in a break as well...
              }
              va_end(ap);
              return ret;
          }
          
          int main()
          {
              int c;
              while( isany(c=getchar(), EOF, '\n', '\0', END_INPUT) {
                  ...
              }
          }
          

          【讨论】:

            【解决方案8】:

            如果您愿意放弃int c 并改用char,则可以使用标准库函数将其编码得更短,同时保持“排除列表”的可扩展性:

            char terminate_on[] = { EOF, '\n', '\0' };    /* needs to end with '\0' */
            char c[2] = { '\0', '\0' };
            
            while ((*c = getchar()) && !strpbrk(c, terminate_on))
                putchar(*c);
            

            虽然只有两个“中断”字符,但效率可能低于显式测试序列。

            请参阅 strpbrk() 了解该函数的作用。

            【讨论】:

              猜你喜欢
              • 2017-03-26
              • 1970-01-01
              • 1970-01-01
              • 2021-10-31
              • 1970-01-01
              • 2022-10-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多