Generate a "readable" backspace in command prompt - c

How can I generate a "readable" backspace in command prompt?
I have a tiny C app and I'm trying to read a backspace from input with getchar() method.
Is there any key combination to trigger this (and still being able to capture it)? (Similar to Ctrl-Z to trigger an EOF)

Backspace is special! Normally you will need to use some raw/unbuffered keyboard I/O mode to capture it.
On Windows you may want to try using getch instead of getchar. See also: What is the difference between getch() and getchar()?

You can use curses function getch() to read backspace.
Chech the following link -
how to check for the "backspace" character in C
In the above link in answer ascii value of backspace is used to read it .

Ascii code of backspace button is 127, so every function returns an integer from terminal input will probably return 127 in case of backspace. Be careful because it is the same code for delete button.
Linux
See this answer first and implement your own getch() then follow Windows code example (obviously without conio.h lib).
Windows
Just add #include<conio.h>in the beginning of your source file.
This is my SSCCE, just need to write something like this
int main(void) {
int c;
while (1) {
c = getch();
if (c == 127) {
printf("you hit backspace \n");
} else {
printf("you hit the other key\n");
}
}
return 0;
}

Related

Why does getchar() only return (char)13 after another key has been pressed? (windows)

I was playing around with the Windows Console API and found some interesting behaviour. Using this function:
void defConsole() {
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode = 0;
GetConsoleMode(hStdIn, &mode);
SetConsoleMode(hStdIn, mode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT));
}
I was able to make it so that the terminal behaves like non-canonical *nix terminals. (Getchar does not wait for enter and doesn't display what you write, like conio.h's getch or unistd.h's getpass). I then tried printing each character written along with its ascii(?) value.
int main() {
char c;
defConsole();
while (1) {
c = getchar();
printf("%c %d\n", c, (int)c);
}
}
However, something interesting happened: When I pressed enter, nothing happened, but the next key I pressed would be overriden by it (ascii code 13), and the next key would print both the last one and itself.
Why does this happen? What can I do to stop this? Should I change it to use winapi's keyboard input functions instead? That seems like an overkill to me.
To conform with C's line-ending standards, \r\n must be replaced with \n. But you can't know if the sequence is \r\n until you get the character after the \r, so it must be buffered until the next character comes in. Try typing Ctrl-J (\n) after the Enter to see what happens.

Ending a Loop with EOF (without enter)

i am currently trying to end a while loop with something like this:
#include <stdio.h>
int main()
{
while(getchar() != EOF)
{
if( getchar() == EOF )
break;
}
return 0;
}
When i press CTRL+D on my Ubuntu, it ends the loop immediately. But on Windows i have to press CTRL+Z and then press ENTER to close the loop. Can i get rid of the ENTER on Windows?
The getchar behavior
For linux the EOF char is written with ctrl + d, while on Windows it is written by the console when you press enter after changing an internal status of the CRT library through ctrl + z (this behaviour is kept for retrocompatibility with very old systems). If I'm not wrong it is called soft end of file. I don't think you can bypass it, since the EOF char is actually consumed by your getchar when you press enter, not when you press ctrl + z.
As reported here:
In Microsoft's DOS and Windows (and in CP/M and many DEC operating systems), reading from the terminal will never produce an EOF. Instead, programs recognize that the source is a terminal (or other "character device") and interpret a given reserved character or sequence as an end-of-file indicator; most commonly this is an ASCII Control-Z, code 26. Some MS-DOS programs, including parts of the Microsoft MS-DOS shell (COMMAND.COM) and operating-system utility programs (such as EDLIN), treat a Control-Z in a text file as marking the end of meaningful data, and/or append a Control-Z to the end when writing a text file. This was done for two reasons:
Backward compatibility with CP/M. The CP/M file system only recorded the lengths of files in multiples of 128-byte "records", so by convention a Control-Z character was used to mark the end of meaningful data if it ended in the middle of a record. The MS-DOS filesystem has always recorded the exact byte-length of files, so this was never necessary on MS-DOS.
It allows programs to use the same code to read input from both a terminal and a text file.
Other information are also reported here:
Some modern text file formats (e.g. CSV-1203[6]) still recommend a trailing EOF character to be appended as the last character in the file. However, typing Control+Z does not embed an EOF character into a file in either MS-DOS or Microsoft Windows, nor do the APIs of those systems use the character to denote the actual end of a file.
Some programming languages (e.g. Visual Basic) will not read past a "soft" EOF when using the built-in text file reading primitives (INPUT, LINE INPUT etc.), and alternate methods must be adopted, e.g. opening the file in binary mode or using the File System Object to progress beyond it.
Character 26 was used to mark "End of file" even if the ASCII calls it Substitute, and has other characters for this.
If you modify your code like that:
#include <stdio.h>
int main() {
while(1) {
char c = getchar();
printf("%d\n", c);
if (c == EOF) // tried with also -1 and 26
break;
}
return 0;
}
and you test it, on Windows you will see that the EOF (-1) it is not written in console until you press enter. Beore of that a ^Z is printed by the terminal emulator (I suspect). From my test, this behavior is repeated if:
you compile using the Microsoft Compiler
you compile using GCC
you run the compiled code in CMD window
you run the compiled code in bash emulator in windows
Update using Windows Console API
Following the suggestion of #eryksun, I successfully written a (ridiculously complex for what it can do) code for Windows that changes the behavior of conhost to actually get the "exit when pressing ctrl + d". It does not handle everything, it is only an example. IMHO, this is something to avoid as much as possible, since the portability is less than 0. Also, to actually handle correctly other input cases a lot more code should be written, since this stuff detaches the stdin from the console and you have to handle it by yourself.
The methods works more or less as follows:
get the current handler for the standard input
create an array of input records, a structure that contains information about what happens in the conhost window (keyboard, mouse, resize, etc.)
read what happens in the window (it can handle the number of events)
iterate over the event vector to handle the keyboard event and intercept the required EOF (that is a 4, from what I've tested) for exiting, or prints any other ascii character.
This is the code:
#include <windows.h>
#include <stdio.h>
#define Kev input_buffer[i].Event.KeyEvent // a shortcut
int main(void) {
HANDLE h_std_in; // Handler for the stdin
DWORD read_count, // number of events intercepted by ReadConsoleInput
i; // iterator
INPUT_RECORD input_buffer[128]; // Vector of events
h_std_in = GetStdHandle( // Get the stdin handler
STD_INPUT_HANDLE // enumerator for stdin. Others exist for stdout and stderr
);
while(1) {
ReadConsoleInput( // Read the input from the handler
h_std_in, // our handler
input_buffer, // the vector in which events will be saved
128, // the dimension of the vector
&read_count); // the number of events captured and saved (always < 128 in this case)
for (i = 0; i < read_count; i++) { // and here we iterate from 0 to read_count
switch(input_buffer[i].EventType) { // let's check the type of event
case KEY_EVENT: // to intercept the keyboard ones
if (Kev.bKeyDown) { // and refine only on key pressed (avoid a second event for key released)
// Intercepts CTRL + D
if (Kev.uChar.AsciiChar != 4)
printf("%c", Kev.uChar.AsciiChar);
else
return 0;
}
break;
default:
break;
}
}
}
return 0;
}
while(getchar() != EOF)
{
if( getchar() == EOF )
break;
}
return 0;
Here it is inconsistent.
If getchar() != EOF it will enter the loop, otherwise (if getchar() == EOF) it will not enter the loop. So, there is no reason to check getchar() == EOF inside the loop.
On the other hand, you call getchar() 2 times, you wait to enter 2 characters instead of only 1.
What did you try to do ?

kbhit() as escape trigger

I want to use kbhit() for "Press any key to continue" function.
However, after I used the kbhit() in a loop, the key-pressed is stored in the stdin.
So in the next scanf(), the key-pressed from before, appears in the input.
int x,b=0;
printf("Press any key to continue...")
while (b==0) {
b=kbhit();
}
system("cls");
printf("Enter number:");
scanf("%d",&x);
So, if the user pressed a key, lets say the letter K, the k appears after "Enter number:".
I've tried looking for solutions, but failed to make any of them work.
I tried to put a backspace character in to the input stream.
I also tried using getch(), however, the user has to press "Enter" in order to continue, so it defeats the original purpose.
I also tried clearing the stdin stream, by closing and opening, but I can't get it to open properly.
EDIT: As what janisz said in the comments, all I needed is to use system("pause"). Although I can't edit As what janisz said in the comments, all I needed is to use system("pause"). Although I can't edit the "Press any key to continue", its sufficient for my purpose. I will continue trying other solutions provided here for better results if possible, but for now, system("pause") is want i need.
EDIT2: Ok, some of you suggested using getch(). From what I saw online, getch() function gets the input from the stream without the char actually showing on the screen, which is what I want. However, when I tried using getch(), the program doesn't continue after I press any key, it waits for me to press the enter key. Is there a problem? I'm using C-Free 4 Standard on Windows 7.
kbhit() returns an integer value indicating whether the user has pressed a key or not. Please note that the key pressed still remains in the buffer. All you have to do is to flush the stdin buffer by using fflush(stdin) statement.
However if you want to use the key pressed by the user you will have to use a getch() or scanf statement after you have used kbhit().
You may read a good article on "How to use kbhit in C and C++" here for exact usage instructions.
see http://support.microsoft.com/kb/43993
essentially, insert this code after you read the character you want:
while (kbhit()) getch(); //clear buffer
fflush (stdin) ; // clear stdin's buffer
you need to flush both the bios kb buffer and stdin.
#include <windows.h>`#include <windows.h>
#include <stdio.h>
#include <conio.h> // for kbhit() only
#include <stdbool.h> // for booleans
void cleaningBuffers()
{
fflush(stdout); // always ok & need!
while (kbhit()) getch(); // clear buffer
if ( fflush(stdin) == 0 ) {;} // undefined, not enough
// flush the bios kb buffer:
if ( fflush(__iob_func()) == 0) {;} // now ok
}
and console buffers is clear...
you should consider flushing the input stream after the key was pressed
int x,b=0;
printf("Press any key to continue...")
for(;;){
if(kbhit()){
fflush(stdin);
break;
}
}
system("cls");
printf("Enter number:");
scanf("%d",&x);
Now your x variable is clean and pretty :)
Try this
while(!kbhit());
getch();
kbhit() is in conio.h, it's a console function. It will not be affected by rediction (but fflush will!). Thus to "eat off" the key pressed, you should use getch(), which is also a console function. As an added bonus, it will only eat off one character, not all.
Edit: Only on rereading your question i wonder: why not use getch() just like that? The kbhit() is useless, unless you do something in the loop.
Furthermore, the POSIX compliant function names would be _getch() and _kbhit() (at least on planet Microsoft).
u can use getchar()...it'll scan and also display onscreen

Capturing a user's "enter" keystroke in C

I'm starting to learn C now and i'm trying to figure out how I would go about capturing when the user hits "enter." I'm looking particularly at the scanf and getc functions but I'm not quite sure how to go about it. When the user hits enter I want to perform some operations while waiting/watching for him to hit enter again... Is "enter" a new line character coming in from the console? Any advice would be much appreciated!
You can check the ascii value using fgetc().
while(condition) {
int c = fgetc(stdin);
if (c==10) {//Enter key is pressed
//your action
}
}
If you just need the input when user presses enter as input you can use scanf or getchar. Here is an example from cplusplus.com
/* getchar example : typewriter */
#include <stdio.h>
int main ()
{
char c;
puts ("Enter text. Include a dot ('.') in a sentence to exit:");
do {
c=getchar();
putchar (c);
} while (c != '.');
return 0;
}
This code prints what you entered to stdin (terminal window).
But if you do not want the input ( i know it's really unnecessary and complicated for a new learner) you should use an event handler.
printf("Hit RETURN to exit"\n");
fflush(stdout);
(void)getchar();
Ref: comp.lang.c FAQ list ยท Question 19.4b
The C language is platform-independent and does not come with any keyboard interaction on its own. As you are writing a console program, it is the console that processes the keyboard input, then passes it to your program as a standard input. The console input/output is usually buffered, so you are not able to react to a single keypress, as the console only sends the input to the program after each line.
However! If you do not demand your console application to be platform-independent, there is a non-standard library <conio.h> in some Windows compilers that has a function called getche();, which does exactly what you want - wait for a single keypress from the console, returning the char that was pressed.

how to make a 'backspace' program in C?

I am creating some library function for print and scan using assembly language and c.
Now when am entering datas it is getting print,but the problem is when i press the backspace button the cursor is moving backwards(but not deleting anything)..I want the backspace button to work properly(ie,to delete the previous character)
so is there any program for that.Please help me.
The simple, albeit somewhat hackish, way is to just write backspace characters (\b) to the console.
For example:
#include <stdio.h>
int main()
{
printf("Testing");
fflush(stdout);
printf("\b\b\b");
fflush(stdout);
return 0;
}
But this type of thing should really be handled by your terminal driver. You don't mention what operating system you're targeting in the question.
Output a backspace, space, and backspace:
int c = getchar();
if (c == '\b')
{
printf("\b \b");
fflush(stdout);
}
If the user's press of a backspace was already echoed by the terminal driver then just do this:
int c = getchar();
if (c == '\b')
{
printf(" \b");
fflush(stdout);
}
if u r doing so then would like to tell you one thing abt consoles
There are 2 types of consoles , one which can recognize control char. called
Active console(Canonical mode) and one which not called row console .
Obviously if u r using unix's terminal then u will be given default as Active mode console
but u can set it to row mode by executing some commands.

Resources