1

I'm trying to make my version of the following C program contained in a famous book of C programming language:

Write a program that print its input one word per line. Here's my code:

#include <stdio.h>
#define OUT 1
#define IN 0

int main(void){
    char c;
    int state = OUT; /*Indicates if we are IN a white space, tab, nl or if we are OUT (a simple letter)*/

    while ((c = getchar()) != EOF)
    {
        if (c == ' ' || c == '\n' || c == '\t')
        {
            state = IN;
            putchar('\n');      
        } else 
            if(state == IN){
                state = OUT;
                putchar(c);
            } 
    }   
    return 0;
}

To test it, I tried as input:

  • "abc" which the program output as "a".
  • "a b c" which the program output as one letter per line.

It is correct to say, that "abc" was trunked because of getchar() function, which memorize just one character in "c" variable? And it is also correct, say that "a b c" were being processed 3 times (3 while iteration) by getchar() function as single char because of a space between every letter?

bersi
  • 75
  • 1
  • 8

1 Answers1

3

It is correct to say, that "abc" was trunked because of getchar() function, which memorize just one character in "c" variable?

It is not correct, getchar parses char by char, it does not truncate, what is happening is that state only gets assigned IN when a space, newline or tab is inputed.

Since the execution of putchar(c) depends on state to be equal to IN it never prints anything unless one of those three blank characters is inputed at some point, in whitch case it will print the next character or \n for one of those 3 blank characters.

And it is also correct, say that "a b c" were being processed 3 times (3 while iteration) by getchar() function as single char because of a space between every letter?

All the 5 characters are read by getchar(), the output will be:

b 
c

For the reasons explained in the previous question.

Footnote

getchar() should be assigned to an int which is its return type, assigning it to a char is problematic since char may be unsigned and EOF is usually -1.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • About your Footnote. For "char may be unsigned" you mean that char could change due to its platform/compiler? – bersi Feb 23 '21 at 18:57
  • 1
    @GabrieleBerselli yes, exactly, it's implementation defined, more on that here https://stackoverflow.com/q/2054939/6865932 – anastaciu Feb 23 '21 at 18:59
  • In the 5 characters read by getchar(), you perhaps forgot "a"? (you wrote just "b c") Only for understand you answer better. – bersi Feb 23 '21 at 19:00
  • @GabrieleBerselli, no, that's what it prints, check it out here https://wandbox.org/permlink/pBhd2qwAWjGUg3Xr – anastaciu Feb 23 '21 at 19:03
  • 1
    @GabrieleBerselli, you see, it only prints when `state` is `IN` or `0` if you prefer, but this only happens when a space is inputed, so `a` does not get printed because there is no space before it. – anastaciu Feb 23 '21 at 19:05
  • 1
    I understand now. I was making a logical error, thinking of your answer just from "state = IN". So you mean that (as your compile demonstrate) first char is "skipped" because we enter in "state = IN" just after the first ' ' char which is just next to "a" char. – bersi Feb 23 '21 at 19:09