The snippet shown has [at least] one logical error and an other error caused by the confusion between the logical boolean operators and bitwise boolean operators.
Logic error:
Your second test on c != EOF
is OR-ed with the test on character not being a space (c != ' ')
...
Since you get to this OR-ed test when c is not EOF (this being the control condition of the while
), the OR-ed test is always true!
...
while (c != EOF)
{
// This test always true regardless of c being a space or not
// Also it should be a logical OR, if at all. The bitwise OR will produce
// odd results if you are not sure of the bit patterns of the operands.
while (c != EOF | c != ' ')
{
putchar(c);
c = getchar();
}
...
Confusion of operator error:
In this instance, you need to use the logical OR (or indeed the logical AND) operators, i.e. ||
and &&
respectively rather than the bitwise boolean operators (|
and &
).
You'll generally find that in C you use the logical operators quite frequently to express boolean conditions, whereby you only need the bitwise operators when you effectively need to mess with bit patterns of variables (e.g. to mask some bits or to force them to be set etc.)
Now, the above was addressing issues in the code "as is", merely explaining why the spaces were handled just like other characters... With regard to the K&R exercise's goal: that of substituting sequence of several spaces with just one space, the logic shown is positively wrong. I'd rather not give it away here, but a few hints:
- introduce a "state" variable which indicates whether the previous character was a space
- use a single while loop (while not EOF or whatever end condition you wish)
- within the loop systematically output the character read, unless the state var is set
- after conditionally outputting the current character, update the state character.
As a general hint, it is often (but not always) a "code smell" (i.e. an indication that the code/logic should be reworked) when you need to repeat end-of-loop condition(s) within a loop and/or introduce multiple spots where you read from some input (here multiple getchar()
)