1

I'm trying to understand how the terminal driver works in conjunction with getchar. Here are a few sample codes i wrote while reading KandR:

Code 1:

#include <stdio.h>

int main(){

  int c = getchar();
  putchar(c);


  return 0;

}

Code 2:

    #include <stdio.h>

    int main(){

    int c = EOF;

    while((c=getchar()) != EOF){
    printf("%c",c);
    }
    return 0;
}

Code 3: //barebones program that emulates functionality of wc command

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

    int main(){
      //nc= number of characters, ns = number of spaces, bl=number of newlines, nw=number of words
      int c = EOF,nc=0,nw=0,ns=0,nl=0, state = OUT;

      while((c=getchar())!=EOF){
        ++nc;
        if(c=='\n'){
          ++nl;
          state = OUT;
        }
        else if(c==' '){
          ++ns;
          state = OUT;
        }

        else{
          if(state == OUT){
          state = IN;
          ++nw;}
        }

      }

      printf("\n%d %d %d %d",nc,nw,ns,nl); 
return 0;
}

I wish to understand when the terminal driver actually hands over the input string to the program. Assume my input is the string "this is a test" and i press enter, then here is how the above mentioned codes work:

code 1: outputs "t" (and the program ends)

code 2: outputs "this is a test", jumps to the next line (because it also outputs the enter i pressed) and waits again for input.

code 3: does not output anything for the above string followed by an enter. I need to press Ctrl+D for the output to be displayed (output is 15 4 3 1)

1) Why in case of code 3 do i need to press Ctrl+D (EOF) explicitly for the input to be sent to my program? To put this in other words, why was my input string sent to my program in case of code 1 and code 2 after i pressed enter? Why didn't it also ask for EOF?

2) Also, in case of code 3, if i do not press enter after the input string, i need to press Ctrl+D twice for the output to be displayed. Why is this the case?

EDIT:

For another input say "TESTING^D", here is how the above codes work:

1) outputs "T" and ends

2) outputs "TESTING" and waits for more input

3) ouputs nothing until another Ctrl+D is pressed. then it outputs 7 1 0 0.

In case of this input, the terminal driver sends the input string to the program when Ctrl+D is received in case of code 1 and code 2. Does that mean /n and Ctrl+D are treated the same way i.e. they both serve as a marker for the terminal driver to send the input to the program? Then why i need to press Ctrl+D twice for the second case?

This http://en.wikipedia.org/wiki/End-of-file says that the driver converts Ctrl+D into an EOF when it is on a newline. But in case of my "TESTING^D" input, it works fine even though the ^D is on the same line as the rest of the input. What can be the possible explanation for this?

user720694
  • 2,035
  • 6
  • 35
  • 57
  • 1
    Addressing your last question: The linked Wikipedia article don't cite a source for that. As far as I remember, `ctrl`+`d` sends `EOF` if the terminal buffer is flushed and otherwise, it flushes the buffer. A newline also flushes the buffer. Unfortunately, I can't find a reference for this at the moment either. HTH – mafso Jun 15 '14 at 14:21

1 Answers1

3

General information:

In case code 2: you also need to do ctrl+D in order to exit.

In fact EOF is achieved by pressing ctrl+D, so what your while loop condition says:

  1. get input from keyboard
  2. store it in c
  3. if the input was not equal to EOF execute the body of the while loop

EOF is nothing but the integer -1, and this can be achieved in the terminal by pressing ctrl+D. So taking this example:

while((c=getchar()) != EOF){
   // execute code
}

printf("loop has exited because you press ctrl+D");

The condition keeps taking input but stops when you press ctrl+D, then it continue to execute the rest of the code.

Answering you questions:

1) Why in case of code 3 do i need to press Ctrl+D (EOF) explicitly for the input to be sent to my program? To put this in other words, why was my input string sent to my program in case of code 1 and code 2 after i pressed enter? Why didn't it also ask for EOF?

In code 2 and 3 (Not only 3), you need to press Ctrl+D because the while loop stops taking input from keyboard only when it reads EOF. In code 1 you are not looping, so when you enter one or more character, the program will read the characters entered but will store the first one only, then it will print it and terminate the program, so no need for EOF in that case because you are not asking for it anywhere in any condition.

2) Also, in case of code 3, if i do not press enter after the input string, i need to press Ctrl+D twice for the output to be displayed. Why is this the case?

If you started typing when the program is expecting input, then after typing at least one character you press ctrl+D, this will tell the program to stop taking input and return the entered characters. After that, if you press ctrl+D again without entering any character before, this will return EOF which will then not satisfy the condition of the while loop and skip to continue executing the rest of the code

CMPS
  • 7,733
  • 4
  • 28
  • 53
  • So if i understand you correctly, /n and Ctrl+D are treated the same way i.e. they both serve as a marker for the terminal driver to send the input to the program? It is only when Ctrl+D is sent alone without any text does it treat it as a EOF? In code 1 and 2: When i press /n or Ctrl+D after an input, the input is made available for putchar? – user720694 Jun 15 '14 at 06:50
  • ctrl+D with input signals the program to process the input. `Enter` appends \n character and send the input to the program. But note that ctrl+D with no input before it will return an EOF @Karan – CMPS Jun 15 '14 at 07:05
  • `Block-reading functions return the number of bytes read, and if this is fewer than asked for, then the end of file was reached.` http://en.wikipedia.org/wiki/End-of-file @Karan – CMPS Jun 15 '14 at 07:07
  • Upvoted! The wikipedia link says that Ctrl+D should be the start of a line for the driver to convert it to an EOF. But when i input "TESTING^D^D" to code 3, my program gives the output and exits, even though the second ^D is on the same line as the input. What am i missing here? – user720694 Jun 15 '14 at 07:31