kbhit() as escape trigger - c

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

Related

Issue with counting upper and lower letters in C

I've written a program which should count upper and lower letters and other signs but it counts anything but when I click Enter and then ^C (EOF). I don't know how to jump over it, hope somebody can help me somehow <3
#include <stdio.h>
#include <ctype.h>
int main()
{
char ch;
int uppers = 0, lowers = 0, others = 0;
while((ch = getchar()) != EOF)
{
if(islower(ch))
lowers++;
else if(isupper(ch))
uppers++;
else
others++;
}
printf("\n\nUpper letters - %d Lower letters - %d Others- %d", uppers, lowers, others);
return 0;
}
Ctrl+C sends a SIGINT which normally just terminates your application.
What you need is Ctrl+D, which triggers EOF.
EDIT: Note that on Windows' default shell you may need Enter, Ctrl+Z, Enter (or F6) instead (though Ctrl+Z does something else entirely in Linux shells, sending a SIGSTOP). See this question.
You could also compare against 0xD instead of EOF to catch Enter, or maybe use 0x1B which will catch Esc. This way you avoid the weirdness of how to trigger the end-of-input on different platforms (unless you want to process an input stream).
Also take a look at this comment above as well as this answer which contain important additional info that I was missing!
CherryDt has already provided an appropriate answer.
But just to add to that, EOF is not a character but instead an end condition. It may be OS dependent. You can't rely on it to work the same manner in every environment. My suggest would be to use any character itself as a condition to terminate loop, rather than an condition which is environment dependent.
NOTE : The solution worked of ending the program with keys worked for me on Windows only when I included a fflush(stdin); after the getchar(). Probably, getchar() takes the input you give and leaves newline character \n in the input stream which was causing problem when I tried to terminate using ctrl+D or ctrl+Z or F6.
But once you include fflush(stdin), this would solve the problem and now the program ends successfully when I use the F6 on Windows. You can also try with above mentioned keys if this does not work for you.
Hope this helps some Windows users if the above answer wasn't working for them.

when control+d is pressed fgets do not stop reading

When you read from stdin using getchar, fgets or some similar function, if you type some text and then put an eof (control+d in linux) you cannot delete the previous text. For example, if I type 'program' and then enter eof by pressing control+d, I can't delete what I typed before, i.e. program.
#include<string.h>
#include<stdlib.h>
int main() {
char buffer[1024] = "";
printf("> ");
if(fgets(buffer,sizeof(buffer),stdin) == NULL){
puts("eof");
}
else{
puts(buffer);
}
return 0;
}
How can this be avoided?
The readline function of The GNU Readline Library I think is my best option to do the job. It's pretty simple to use but it uses dynamic memory to host the string so you have to use the free function to free up the memory. You can find more information by opening a terminal and typing 'man readline'.
The code would look like this:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <readline/readline.h>
int main() {
char *ptr = readline("> ");
if(!ptr){
puts("eof");
}
else{
puts(ptr);
}
free(ptr);
return 0;
}
To be able to use readline with gcc you must pass it -lreadline
When fgets reads a line, what will happen is that it will read characters from the specified stream until it encounters a '\n' or EOF, until it has read the specified maximum size to read or a read error occurs. It does not see what you are doing on your keyboard at all. It only sees the stream, but it is the terminal that sends the data to the stream.
What's happening when you are editing the input has absolutely nothing to do with fgets. That's the terminals job.
As Eric Postpischil wrote in the comments:
Pressing control-D in Linux does not signal EOF. It actually means “Complete the current read operation.” At that point, if characters have been typed, they are immediately sent to the program, whereas the system would usually wait until Enter is pressed. If no characters have been typed, the read operation completes with zero characters read, which some I/O routines treat as an EOF, and that is why programs may seem to receive an EOF when control-D is pressed at the start of a line of input. Since the data is sent to the program, of course there is no way to undo it—it has already been sent.
I guess there is some way to alter the behavior of pressing C-d, but then you need to decide what it should do instead. If you want it to do "nothing" instead of sending the data to stdin I cannot really see what you have won. The only use case I can see with this is if you for some reason are having a problem with accidentally pressing C-d from time to time.
One thing you could do is to take complete control of every keystroke. Then you would have to write code to move the cursor every time the user presses a key, and also write code to remove characters when the user is pressing backspace. You can use a library like ncurses for this.
It can't be avoided. Simply put, Ctrl+D ends the current read operation.
If you want to ignore this, make your own fgets based on fgetc and have it ignore end-of-file.

Generate a "readable" backspace in command prompt

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;
}

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.

Confused about getchar() function

I am confused about getchar()'s role in the following code. I mean I know it's helping me see the output window which will only be closed when I press the Enter key.
So getchar() is basically waiting for me to press enter and then reads a single character.
What is that single character this function is reading? I did not press any key from the keyboard for it to read.
Now when it's not reading anything, why does it not give an error saying "hey, you didn't enter anything for me to read"?
#include <stdio.h>
int main()
{
printf( "blah \n" );
getchar();
return 0;
}
That's because getchar() is a blocking function.
You should read about blocking functions, which basically make the process wait for something to happen.
The implementation of this waiting behavior depends on the function, but usually it's a loop that waits for some event to happen.
For the case of the getchar() function, this probably is implemented as a loop that constantly reads a file (stdin for this case) and checks weather the file is modified. If the file is modified, the loop behaves by doing something else.
The getchar() function will simply wait until it receives a character, holding the program up until it does.
A character is sent when you hit the enter key; under a Windows OS, it will send a carriage return (CR) and a line-feed (LF).
See this CodingHorror post for a nicely put explanation.
(...the explanation of the CR+LF part, not the getchar() blocking part)
Try this:
#include <stdio.h>
int main(int argc, char *argv[])
{
char ch;
printf("I'm now going to block until you press something and then return... ");
ch = getchar();
if (ch >= 0)
printf("\nYou pressed %c\n", ch);
else
printf("\nAliens have taken over standard input! Run!\n");
return 0;
}
getchar() will cause your program to go to sleep until a keyboard (or whatever is attached to stdin) interrupt is received. This means it's blocking, no additional code will execute until getchar() returns.
It's very, very helpful to look at the return value of a function in order to understand it.
Any function may block, unless it provides some mechanism to prevent blocking. For instance, open() allows a O_NONBLOCK flag which is helpful for opening slow to respond devices like modems. In short, if it gets input from a terminal or has to wait to get an answer from the kernel or some device, there's a very good chance it might block.
getchar() blocks your program's execution until a key is pressed. So, there's no error if no key is pressed, getchar() will wait for it to happen :)
You can learn more about how getchar behaves here:
http://www.cppreference.com/wiki/c/io/getchar
...this should answer your question:)
I think what confuses you is that the Enter key is needed befor the program continues. By default, the terminal will buffer all information until Enter is pressed, before even sending it to the C program.
see discussion of Enter problem here

Resources