0

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

我试过了:

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

哪个不起作用,如果我输入:天气(+输入)。它没有终止循环。

我怎样才能使这项工作?

启发我

4

8 回答 8

5

你可以使用这样的东西:

int c = 0;
while((c=getchar()) != EOF) {
  if ((c == 0) || (c == '\n'))
    break;
  putchar(c);
}
于 2011-11-06T13:20:51.037 回答
3
while ((c = getchar()) != EOF && c != '\n' && c != '\0')
{
  // loop body
}

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

于 2011-11-06T13:47:19.423 回答
2

我认为这应该有效:

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

但这样做可能会更好:

int c=getchar();
while( c != EOF && c!='\n' && c!='\0'){
    putchar();
    c=getchar();
}
于 2011-11-06T13:26:26.273 回答
1

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

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

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

尽管基于评估的顺序,这可能是未定义的,而且看起来很混乱。

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

于 2011-11-06T13:22:51.613 回答
0

It does not work because EOF || '\n' || '\0' is a boolean expression which will always evaluate to true so the condition boils down to if( c != true ), which is only true if c is nul, which getchar() will not normally return.

Assignments in conditions are always ill-advised, and some compilers will issue a warning unless the assignment itself is enclosed in parenthesis. This is to warn against the accidental use of = where the more usual == was intended in a condition.

In C you must have separate boolean expressions even when each tests the same variable:

int c = getchar() ;
if( c != EOF && c != '\n' && c != '\0' )
    ...
于 2011-11-06T16:23:20.657 回答
0

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

#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) {
        ...
    }
}
于 2011-11-06T16:40:33.040 回答
0

考虑您的代码,例如

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

intint你写的函数在哪里,memchr但需要一个整数数组。:-)

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

于 2011-11-06T14:51:42.947 回答
0

如果您愿意放弃int cchar改用,那么可以使用标准库函数对其进行更短的编码,同时保持“排除列表”的可扩展性:

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()该功能的作用。

于 2011-11-14T16:32:00.807 回答