0

I have a simple program which I want to close it immediately when I press the backspace(or any other key). But I do not want to scan anything between the codes. Here is the code :

int main()
{
    int x;
    puts("hello");
    puts("hi");
    f1();
    scanf("%d", &x);
    f2();
    printf("%d",x);
}

void f1() {
...
}
void f2() {
...
}
CKoorosh
  • 96
  • 9

1 Answers1

0

The following solution only applies to the Microsoft Windows platform, because the question has been tagged with "windows". The solution may also work on other platforms, but this is not guaranteed, as it uses functions that are not part of the official ISO C standard.

You can use the function _kbhit to determine whether a key has been pressed. If that function returns nonzero indicating that a keystroke is waiting in the input buffer, then you can call the function _getch or _getche without risk of the function blocking. You can then compare the returned character with the backspace character '\b' to determine whether a backspace was pressed.

However, in your case, using these functions to check for a backspace keystroke will not work together with scanf, for two reasons:

  1. According to this page from the official Microsoft documentation, the console I/O functions are not compatible with the stream I/O functions (printf, scanf, etc.)
  2. The scanf function call will block the whole thread while waiting for the user to input the whole number and press ENTER.

Therefore, it would be best to read every character one by one from the console with _getche, check if it is a backspace, and if not, write it to your own input buffer. After the user presses ENTER, you can then convert the buffer contents into a number using strtol, atoi or sscanf.

I have changed your code to the following to accomplish this:

#include <stdlib.h>
#include <conio.h>

int main()
{
    const int MAX_INPUT = 80;
    char input_buffer[MAX_INPUT + 1];
    char c;
    int i;

    int x;

    _cputs( "hello\n" );
    _cputs( "hi\n" );

    f1();

    //this finite loop prevents a buffer overrun
    for ( i = 0; i < MAX_INPUT; i++ )
    {
        c = _getche();

        //when using console I/O functions, we must check
        //for carriage return '\r' instead of newline '\n'
        if ( c == '\r' ) break;

        if ( c == '\b' ) return 0;

        input_buffer[i] = c;
    }

    input_buffer[i] = '\0';

    //we must print a newline '\n' after encountering a 
    //carriage return '\r', because _getche does not echo it
    _cprintf( "\n" );

    // NOTE:
    // Using the function strtol instead of atoi allows you
    // to check if an error occured while converting.
    x = atoi( input_buffer );

    f2();

    _cprintf( "%d", x );

    return 0;
}

Because, as already mentioned, console I/O functions are not compatible with stream I/O functions, I have also replaced the functions puts and printf with the console versions _cputs and _cprintf.

Please note that this code will not compile because, just as your original code, it contains two function calls to undeclared functions. However, if you remove these two function calls, then my posted code will compile and run properly (at least on my system).

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39