Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getchar() in C is completed without pressing Enter

Tags:

c

io

getchar

From my previous post, I come to know that getchar() completes only when we press Enter. Let's consider this code:

#include<stdio.h>
main()
{
  getchar();
  getchar();
  getchar();
  getchar();
  getchar();


}

I expected it to run like this: I press some key1 then press Enter, then key2 an Enter, then key3 and Enter, then key4 and Enter and at last key5+Enter, the program should terminate now. This is not what actually happens. What happens is this: I press some key1 then press Enter, then key2 an Enter, then key3 and Enter, the program eventually terminates!

  • Why don't the last two getchar() work?

Another weird thing that I observed is that if I do: key1,key2,key3,key4+Enter then the program terminates. E.g. If I press q,w,e and r in succession and then Enter, the program terminates.

  • Why not all the getchar() ask for enter? Does this mean that getchar() take any other key as Enter? But then does the next key is taken as the input for the next getchar()?

Let's consider another code:

#include<stdio.h>
main()
{

  int c=getchar();
  int d=getchar();
  int e=getchar();
  printf("2 getchar are remaining\n");
  int f=getchar();
  int g=getchar();
  printf(" c is %d, d is %d, e is %d, f is %d and g is %d",c,d,e,f,g);

} 

I input: ABCDEFG then Enter. The line 2 getchar are remaining should be printed as soon as I press C or D. But it is printed at last, means that all the getchar()s get executed simultaneously-- this is weird.

  • Isn't the program get executed line by line? I.e. after the third getchar, printf() should work. But it works at last when all the getchar()s are executed.
like image 493
user31782 Avatar asked Oct 17 '25 17:10

user31782


1 Answers

It's not true that getchar() completes after you press enter. getchar() completes whenever there are characters to read. This difference is significant: see, for example, if you use your program with the standard input redirected to a file:

$ hexdump -C abcd_file 
00000000  61 62 63 64 65                                    |abcde|
00000005

$ ./in < abcd_file 
$

Notice that "abcd_file" is a file that contains "abcde", no newline and your program finishes without requiring a newline anywhere. That's because the file is providing characters all the time and not waiting for a newline.

Common terminals or terminal emulators, on the other hand, have an operation mode that is called the "canonical mode". Canonical mode means that the terminal supports "command line processing facilities" and will not signal an available character until the user presses ENTER. That's where the incorrect "getchar() waits for ENTER" story comes from. You can switch your terminal out of canonical mode and see it retrieving all the characters without the need for pressing enter:

$ stty -icanon; ./in; stty icanon
ggggg$

In this case 5 characters without an enter made the program to finish.

Finally, the reason for getchar() look like it is returning early is because it also returns the ENTER characters. So "a\nb\nc\n" is 6 characters, the first 5 are returned by getchar(), the sixth is deleted from the terminal queue after the program finishes. Typing "abcd\n" also means that getchar() will be immediatelly available for 5 consecutive reads, because there are 5 characters stored in the terminal queue.

http://www.gnu.org/software/libc/manual/html_node/Noncanonical-Input.html#Noncanonical-Input

like image 143
hdante Avatar answered Oct 20 '25 09:10

hdante