Replacing strings to have a single blank In Kernighan and Ritchie (the C programming language):


  Write a program to copy its input to its output, replacing each string of one or more blanks by a single blank.


I wrote the following code.  Do you have advice to improve it?

#include &lt;stdio.h&gt;

/* copy input to output, replacing each 
string of one or more blanks by a single blank */

main(){

    int c;
    double nc;
    char otherBlank;

    otherBlank = 'f';

    while ((c = getchar()) != EOF){
        if (otherBlank == 't' &amp;&amp; c != ' '){
            /* read a non blank and had a blank before */
            putchar(' ');
            putchar(c);
            otherBlank = 'f';
        }

        else if (c == ' ')
            /* read a blank */
            otherBlank = 't';

        else
            /* read a non blank and had no blank before */
            putchar(c);

    }


}
There a few concerns I have with this program.  Let's go through it line by line:


You don't declare what you are returning from main(), or what parameters you are going to take in.  You should always be declaring these instead of letting the compiler assume them.

int main(void)


You asked in the comments why we should declare this to return an int and not void.  We don't want to just throw away that useful exit status information. There is great answer here that goes into great detail as to why, you should take a look over there.

"But wait!", you say.  "We didn't actually return anything from our main function!  How does this black magic work?"  Yep, I know.  That is just what is declared in the standards.


  C99 &amp; C11 §5.1.2.2(3):
  
  "...reaching the } that terminates the main() function returns a value of 0."

You don't use your nc variable in your program.  It should be removed.
You declare otherBlank as a char on one line and assign it the character f on the next line.  You should be assigning on the same line as you are declaring in this case.  
Analyzing your program further, it is questionable as to why you aren't using a boolean value to represent otherBlank.  You only seem to be using it as a "flag" of a sort, so it makes sense to me to represent it as the bool type.  Keep in mind that you will have to include &lt;stdbool.h&gt; if you choose to change this.
Further refactoring your program, there is no need for the otherBlank variable.  Use a while loop to capture all of the ' ' characters and then output only one ' ' character.  Then continue with the printing of the other non-blank characters.
You don't check putchar for it's return value, as you should be doing.  @Michael went into great detail with this, give his answer a look and an upvote to see why!




Here is what I managed to come up with:

#include &lt;stdio.h&gt;

int main(void)
{
    int c;
    while ((c = getchar()) != EOF) {
        if (c == ' ') {
            while ((c = getchar()) == ' ');
            if (putchar(' ') == EOF) return -1;
            if (c == EOF) break;
        }
        if (putchar(c) == EOF) return -1;
    }
}


Here is how this could be further improved:


Use the function fgets() to capture the input once; looping over each character to capture it manually isn't very efficient (and if your program doesn't handle input properly, it could be dangerous).
Store the input string in a character array and loop over the characters to test them for ' '.  Then make the necessary changes and print out the entire string at once, instead of looping and printing out the individual characters (again, inefficient).