K&R Exercise 1-9: output the input, replacing multiple blanks by a single blank

In the for-loop statement, you're having the bug.

for(ch = getchar(); (ch = getchar()) != EOF; lch = ch){...}

Here, you're storing first character in ch, and then again testing if (ch!=EOF) by again reading character input.

Remove ch=getchar() from the initialisation statement; let it be in the second part.

for(;(ch = getchar()) != EOF; lch = ch){...}

Also, you will have to initialise your lch before making it run as lch will not have any value stored in it before making comparison in the first iteration of the loop. So, let lch=0 be initialised first.

for(lch = 0; (ch = getchar()) != EOF; lch = ch){...}

Consider enabling warnings in your compiler, it would probably detect and warn about this issue, so you could fix it.

The above would solve your problem.

(Thanks to Blue Moon and hyde for helping me modify the answer.)


You call getchar twice in the loop initialization:

 for(ch = getchar(); (ch = getchar()) != EOF; lch = ch)

Instead, you should call it once in the initialization (to get the first char) and then in the end of the iteration (to get the next characters):

int ch, lch = 0; // avoid using uninitialized variable

for(ch = getchar(); ch != EOF; lch = ch)
{
        if(ch == ' ' && lch == ' ')
                ;
        else putchar(ch);

        ch = getchar();
} 

UPD: Thanks Blue Moon and shekhar suman for pointing out the issue with lch


The problem is that the first iteration of your loop calls getchar twice - once when initializing the ch variable, and one more time when checking ch against EOF.

Dropping ch = getchar() will fix this problem:

for( lch = '?' ; (ch = getchar()) != EOF; lch = ch) {
    ...
}

Note that you need to init lch with any value other than space.