Aurum
Aurum

Reputation: 35

while(getchar() != multiple arguments)

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

Answers (8)

FrankH.
FrankH.

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

glglgl
glglgl

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

Clifford
Clifford

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

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

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

John Bode
John Bode

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

bames53
bames53

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

slugonamission
slugonamission

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

Mat
Mat

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

Related Questions