Home > OS >  printf() first character not displayed after using _getche()
printf() first character not displayed after using _getche()

Time:09-23

If I input test and press [esc], the output is he result is "test" for some reason. The T gets removed from the beginning. But if I reach the limit of 20 characters, The result is "..." is displayed normally. The really weird part is, that when using certain characters before of the uppercase T, it is displayed, but when using others it remains the same (he result is "..."). The code is as follows:

#include "stdio.h"
#include "conio.h"

int main()
{
    printf("conio.h _getche test\n\n");
    char text[21], c;
    int n = 0;
    printf("Please enter your text: ");
    while (1)
    {
        if (n == 20)
        {
            text[n] = 0;
            break;
        }
        c = _getche();
        if (c == 27)
        {
            text[n] = 0;
            break;
        }
        text[n] = c;
        n = n   1;
    }
    printf("\n\nThe result is \"%s\"\n", text);
    return 0;
}

I'm really struggling to comprehend what is going on... All help is welcome, thanks in advance.

CodePudding user response:

I think what is happening is you are simply breaking the terminal’s sequence recognition software.

Almost all modern terminal emulators support Virtual Terminal Control Sequences. Importantly, the Windows Console has also been updated to support VT sequences just as well as the Windows Terminal.

Most VT control sequences begin with an Esc character ('\033' or (char)27).

By using _getche(), you are sending that Esc sequence initializer to the terminal. And since escape sequences are a mess (not all of them begin with ESC [), the terminal patiently reads characters...

...until it gets that 'T' and can definitively say “this is not a valid control sequence” — at which point it can do nothing but throw it all out and continue on as if nothing had happened. You loose random stuff and wonder what happened.

What you should learn from this is:

Don’t echo control characters back to the user

Obnoxiously, this means that you cannot really put _getche() to any good use. Remove it from your repertoire. If you must have an echoing function, write one that sanitizes its inputs:

int my_getche()
{
  int c = _getch();
  if ((c < 0x80) && isprint( c ))
  {
    putchar( c );
  }
  return c;
}
  • Related