Reputation: 35
This is a K&R exercise. It's supposed to substitute a single space for double or more. Instead it exactly mirrors input, spaces and all. Also, why do I have to use EOF (ctrl-d) in other exercises and RETURN (Enter) for this one? (I'm running it on Ubuntu but using ssh from a mac.)
#include <stdio.h>
main()
{
int c;
c = getchar();
while (c != EOF)
{
while (c != EOF | c != ' ')
{
putchar(c);
c = getchar();
}
putchar(c);
c = getchar();
while (c == ' ' | c != EOF)
c = getchar();
}
Upvotes: 0
Views: 257
Reputation: 914
That's a lot of gets and puts, and checking of values. Here's something cleaner that also takes care of tabs.
void main (void)
{
int F_space=F_tab=0; // Flags for special chars
char ch;
do
{
ch = getchar();
// test for special characters
switch (ch)
{
case ' ': // space
F_space = 1;
continue;
case '\t': // tab
F_tab = 1;
continue;
default: // anything else
// output a space if necessary
if (F_space || F_tab) {
F_space = F_tab = 0; // clear flags
putchar (' ');
}
break;
}
// output the character
putchar (ch);
break;
}
while (ch != EOF);
Upvotes: 0
Reputation: 75305
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:
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()
)
Upvotes: 3
Reputation: 2031
Try this loop:
while (c != EOF)
{
if (c == ' ')
{
putchar(c);
while(c == ' ' && c != EOF)
c = getchar();
}
else
{
if (c != EOF)
putchar(c);
c = getchar();
}
}
Upvotes: 1
Reputation: 19467
There are two problems with your code.
The first is that you are trying to use the logical-OR operator (||), but you are using the bit-wise-OR (|). The second is that you should be using logical-AND rather than logical-OR, anyway:
while (c != EOF && c != ' ')
Upvotes: 1