Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid pressing Enter with getchar() for reading a single character only?

In the next code:

#include <stdio.h>  int main(void) {      int c;      while ((c=getchar())!= EOF)           putchar(c);    return 0; } 

I have to press Enter to print all the letters I entered with getchar, but I don't want to do this, what I want to do is to press the letter and immediately see the the letter I introduced repeated without pressing Enter. For example, if I press the letter 'a' I want to see an other 'a' next to it, and so on:

aabbccddeeff..... 

But when I press 'a' nothing happens, I can write other letters and the copy appears only when I press Enter:

abcdef abcdef 

How can I do this?

I am using the command cc -o example example.c under Ubuntu for compiling.

like image 366
javier Avatar asked Nov 25 '09 17:11

javier


People also ask

Does Getchar wait for enter?

The way it works is that getchar() reads a character from the input buffer. Therefore, if the buffer is empty, it waits for it to obtain values before it reads one. Input is only sent to the buffer from the keyboard after you press the enter key.

How many characters does function getchar () read?

The function getchar() reads a single character from the standard input and returns the character value as the value of the function, but to accommodate a possible negative value for EOF, the type of the value returned is int.

What does getchar () do in C?

getchar is a function in C programming language that reads a single character from the standard input stream stdin, regardless of what it is, and returns it to the program. It is specified in ANSI-C and is the most basic input function in C.


1 Answers

This depends on your OS, if you are in a UNIX like environment the ICANON flag is enabled by default, so input is buffered until the next '\n' or EOF. By disabling the canonical mode you will get the characters immediately. This is also possible on other platforms, but there is no straight forward cross-platform solution.

EDIT: I see you specified that you use Ubuntu. I just posted something similar yesterday, but be aware that this will disable many default behaviors of your terminal.

#include<stdio.h> #include <termios.h>            //termios, TCSANOW, ECHO, ICANON #include <unistd.h>     //STDIN_FILENO   int main(void){        int c;        static struct termios oldt, newt;      /*tcgetattr gets the parameters of the current terminal     STDIN_FILENO will tell tcgetattr that it should write the settings     of stdin to oldt*/     tcgetattr( STDIN_FILENO, &oldt);     /*now the settings will be copied*/     newt = oldt;      /*ICANON normally takes care that one line at a time will be processed     that means it will return if it sees a "\n" or an EOF or an EOL*/     newt.c_lflag &= ~(ICANON);                /*Those new settings will be set to STDIN     TCSANOW tells tcsetattr to change attributes immediately. */     tcsetattr( STDIN_FILENO, TCSANOW, &newt);      /*This is your part:     I choose 'e' to end input. Notice that EOF is also turned off     in the non-canonical mode*/     while((c=getchar())!= 'e')               putchar(c);                       /*restore the old settings*/     tcsetattr( STDIN_FILENO, TCSANOW, &oldt);       return 0; } 

You will notice, that every character appears twice. This is because the input is immediately echoed back to the terminal and then your program puts it back with putchar() too. If you want to disassociate the input from the output, you also have to turn of the ECHO flag. You can do this by simply changing the appropriate line to:

newt.c_lflag &= ~(ICANON | ECHO);  
like image 195
Lucas Avatar answered Oct 19 '22 23:10

Lucas