如何使用 getchar 作为 while 循环的条件,并在 (c=getchar()) = EOF 或 '\n' 或 '\0' 时终止。
我试过了:
int c=0;
while((c=getchar()) != EOF || '\n' || '\0'){
putchar();
}
哪个不起作用,如果我输入:天气(+输入)。它没有终止循环。
我怎样才能使这项工作?
启发我
如何使用 getchar 作为 while 循环的条件,并在 (c=getchar()) = EOF 或 '\n' 或 '\0' 时终止。
我试过了:
int c=0;
while((c=getchar()) != EOF || '\n' || '\0'){
putchar();
}
哪个不起作用,如果我输入:天气(+输入)。它没有终止循环。
我怎样才能使这项工作?
启发我
你可以使用这样的东西:
int c = 0;
while((c=getchar()) != EOF) {
if ((c == 0) || (c == '\n'))
break;
putchar(c);
}
while ((c = getchar()) != EOF && c != '\n' && c != '\0')
{
// loop body
}
这是因为&&
运算符 a) 总是首先计算 LHS 表达式,并且 b) 引入了一个序列点,因此 LHS 表达式中的任何副作用(例如将结果分配给getchar
to c
)将在计算 RHS 表达式之前应用。
我认为这应该有效:
int c;
while( (c=getchar()) != EOF && c!='\n' && c!='\0') {
putchar();
}
但这样做可能会更好:
int c=getchar();
while( c != EOF && c!='\n' && c!='\0'){
putchar();
c=getchar();
}
可悲的是,您需要将其分解为多个语句。您正在尝试执行多个事物的逻辑或,并且给定“真”是“任何非零”,并且字符只是数字,其中大部分是非零的,您基本上是在说“而 c 不是 EOF,或真或真”。
我不完全确定 C 规范,但重写语句如下可能有效:
while((c=getchar()) != EOF && c!='\n' && c!='\0')
尽管基于评估的顺序,这可能是未定义的,而且看起来很混乱。
更好的解决方案是将“c=getchar()”移到其他地方,然后检查 while 标头中的 C 值。这确实意味着您必须将“c=getchar()”都移到循环之外,并且移到 while 循环体的底部。
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' )
...
一个非常大但非常个性化的解决方案可能是:
#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) {
...
}
}
考虑您的代码,例如
while (intint((int []){ EOF, '\n', 0 }, c=getchar(), 3) ...
intint
你写的函数在哪里,memchr
但需要一个整数数组。:-)
这个答案是半个笑话,因为其他答案已经很好地解决了这个问题,但关键是经常用正确的接口定义正确的函数可以使你的代码更简单。
如果您愿意放弃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()
该功能的作用。