sphere
sphere

Reputation: 43

Clarifying K&R exercise 1-9

I have a few questions on this exercise. Here is the code I'm dealing with:

#include <stdio.h>

int main (void)
{
    int c;
    int inspace;

    inspace = 0;
    while((c = getchar()) != EOF)
    {
        if(c == ' ')
        {
            if(inspace == 0)
            {
                inspace = 1;
                putchar(c);
            }
        }

        if(c != ' ')
        {
            inspace = 0;
            putchar(c);
        }
    }
    return 0;
}

(Sorry I'm having a lot of trouble comprehending how these programs work because they're so simple and lack description on how they actually work)

First of all, how does putchar(c) not output the same exact data that came in. Despite it checking for a blank or != blank, it still says to output "c" which is just getchar(c) meaning whatever was inputted. I see no code that specifies to delete extra spaces and output just one space. Where does the code specify that that is what must take place? I'm having trouble understanding how getchar/putchar works it seems to me.

Also, what importance does inspace == 1 or 0 have? If inspace is == 1 then it just outputs the characters inputted back out. There's nothing saying that the extra blanks are deleted and inspace isn't defined as anything except 0 or 1, there's nothing defining it as a space so how can it possibly have any real meaning as to what the program is doing?

I'm really confused, where is the code that's replacing the spaces and how does it work? Is there a simpler book I should be learning from that explains the solutions?

Upvotes: 2

Views: 249

Answers (4)

John Kugelman
John Kugelman

Reputation: 362037

First of all, how does putchar(c) not output the same exact data that came in. Despite it checking for a blank or != blank, it still says to output "c" which is just getchar(c) meaning whatever was inputted. I see no code that specifies to delete extra spaces and output just one space. Where does the code specify that that is what must take place? I'm having trouble understanding how getchar/putchar works it seems to me.

You are correct that if putchar is called, it just outputs the input character. The key to this program is that putchar isn't called on every input character. The various if statements control when it is called. At a high level, the program avoids calling putchar on the second, third, fourth, etc., spaces if there are multiple spaces in a row. It's only called on the first space.

Also, what importance does inspace == 1 or 0 have? If inspace is == 1 then it just outputs the characters inputted back out. There's nothing saying that the extra blanks are deleted and inspace isn't defined as anything except 0 or 1, there's nothing defining it as a space so how can it possibly have any real meaning as to what the program is doing?

Don't think of it as spaces being deleted. Think of it as them being omitted. Sometimes putchar is called, sometimes it isn't. Look at the loop and try to figure out what conditions would cause putchar not to be called.

Importantly, look at what happens if you start a loop iteration, inspace == 1, and c == ' '. What happens?

It might help to put together a table showing when putchar is and isn't called.

Is putchar(c) called?
=====================

             | c == ' ' | c != ' '
-------------+----------+---------
inspace == 0 |    Y     |    Y
inspace == 1 |    N     |    Y

Upvotes: 4

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726987

how does putchar(c) not output the same exact data that came in.

When the code reaches putchar(c), it outputs the same exact character that came in. However, the code may not be reaching putchar(c) on some of the iterations.

what importance does inspace == 1 or 0 have?

Once the program sets inspace to 1, it stops printing further space characters, because the code will not reach putchar(c) on second and subsequent iterations of the loop.

inspace is set to 1 after printing the first space in a sequence of one or more spaces. If inspace is set to zero coming into the first conditional, a space would be printed; otherwise, no space would be printed.

Here is a diagram that explains what is happening:

Diagram

The program starts in the black circle, and proceeds to one of two states, depending on the input character:

  • If the character is space, the state on the left is entered, when the first space is printed, and the rest of spaces are ignored (i.e. inspace is set to 1)
  • If the character is non-space, the state on the right is entered, when each character is printed.
  • Each time a new character is read the program decides if it wants to switch the state, or to remain in the current state.

Note: the diagram is not showing the EOF to save some space. When EOF is reached, the program exits.

Upvotes: 1

R Sahu
R Sahu

Reputation: 206717

Think about the logic in this block when there are two ore more consecutive ' ' characters in the input.

    if(c == ' ')
    {
        if(inspace == 0)
        {
            inspace = 1;
            putchar(c);
        }
    }

When the first space character is encountered, the code enters the nested if block and prints the character.

When the second space character is encountered, the code does not enter the nested if block and the character is not printed.

If you follow this logic, you'll notice that if there are two or more consecutive space characters in the input, only one is printed.

Upvotes: 2

Eugene Sh.
Eugene Sh.

Reputation: 18381

The first if block along with the inner one is saying, "If the input is a space and the inspace flag is zero, print it, and also set the flag to one". I.e. print space if it is the first one, and indicate the next one won't be the first. The second block is saying "If the input is not space, print it and reset the previous spaces flag so the next encountered space will be considered the first one.". That's all.

Upvotes: 0

Related Questions