Reputation: 35
How to use getchar as the condition for a while loop and having it terminate when (c=getchar()) = EOF or '\n' or '\0'.
I tried:
int c=0;
while((c=getchar()) != EOF || '\n' || '\0'){
putchar();
}
Which did not work, If i entered: WEATHER(+enter). It did not terminate the loop.
How can i make this work?
Enligthen me
Upvotes: 0
Views: 1681
Reputation: 18217
If you're willing to forgo the int c
and use char
instead then one can code it shorter using standard library functions, while keeping the 'exclusion list' extensible:
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);
Although for just two "break" characters, that's probably less efficient than an explicit test sequence.
See strpbrk()
for what that function does.
Upvotes: 0
Reputation: 91029
A quite oversized, but very individual solution could be:
#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) {
...
}
}
Upvotes: 0
Reputation: 93476
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' )
...
Upvotes: 0
Reputation: 215259
Factor your code, e.g.
while (intint((int []){ EOF, '\n', 0 }, c=getchar(), 3) ...
Where intint
is a function you write like memchr
but takes an array of ints. :-)
This answer is half a joke, since the other answers solve the the problem sufficiently well already, but the point is that often defining the right function with the right interface can make your code much simpler.
Upvotes: 0
Reputation: 123468
while ((c = getchar()) != EOF && c != '\n' && c != '\0')
{
// loop body
}
This works because the &&
operator a) always evaluates the LHS expression first, and b) introduces a sequence point, so any side effects in the LHS expression (such as assigning the result of getchar
to c
) will be applied before the RHS expression is evaluated.
Upvotes: 3
Reputation: 88155
I think this should work:
int c;
while( (c=getchar()) != EOF && c!='\n' && c!='\0') {
putchar();
}
but it might be better to just do:
int c=getchar();
while( c != EOF && c!='\n' && c!='\0'){
putchar();
c=getchar();
}
Upvotes: 2
Reputation: 9642
Sadly, you'll need to decompose it into multiple statements. You are trying to perform the logical or of multiple things, and given "true" is "anything non-zero", and characters are just numbers, most of which are non-zero, you are basically saying "while c is not EOF, or TRUE or TRUE".
I'm not entirely sure on the C specification, but rewriting the statement as follows might work:
while((c=getchar()) != EOF && c!='\n' && c!='\0')
This could be undefined though based on the order of evaluation, and it looks messy.
A better solution is to move "c=getchar()" somewhere else, and check for values of C in the while header instead. This does mean you'll have to move "c=getchar()" both outside the loop, and to the bottom of the while loop body though.
Upvotes: 1
Reputation: 206699
You could use something like this:
int c = 0;
while((c=getchar()) != EOF) {
if ((c == 0) || (c == '\n'))
break;
putchar(c);
}
Upvotes: 5