1

Why does the program return no ASCII values when I press the keys " F1 - F12, Delete, Caps Lock, Num Lock "

#include<stdio.h>

int main()
{
char a;
clrscr();
a= getche();

printf("\n a= %c ASCII = %d ASCII = %hhu",a,a,a);
// used hhu as it was told in SO it helps to print ASCII

getch();
return 0;
}

It returned the value 0. Why is it so? And while pressing Num Lock and Caps Lock it takes no action. (note : I haven't test all the keys) Please correct the program if there is any mistake. I have used Turbo c++ to write the program.

Thank You

MELWIN
  • 1,093
  • 4
  • 12
  • 19
  • possible duplicate of [getch and arrow codes](http://stackoverflow.com/questions/10463201/getch-and-arrow-codes) – xxbbcc Jan 23 '14 at 04:49
  • @xxbbcc there is nothing mentioned about the Keys I have asked for. – MELWIN Jan 23 '14 at 05:05
  • Can you provide the compiler command line? Running `gcc` gives me three undefined references. – merlin2011 Jan 23 '14 at 05:25
  • @merlin2011 I did not understand what you are asking. – MELWIN Jan 23 '14 at 05:36
  • @MELWIN Your question is about keys not having ASCII values and the duplicate answers describe the behavior of `getch()` which applies to your question (regardless of the actual keys). – xxbbcc Jan 23 '14 at 05:52
  • @MELWIN, which compiler are you using to build your code, and which libraries are you linking? – merlin2011 Jan 23 '14 at 06:12
  • @xxbbcc no I asked why there is no ascii values. Sad the question was marked duplicate. and no upvotes :( . I know how getch() works (mostly). That is not what I have asked. thank you – MELWIN Jan 23 '14 at 07:11
  • @merlin2011 I am using Turbo C++. I am using stdio.h library in the code. no external libraries are being used. the OS used is windows 7. Why you asked for compiler details ? – MELWIN Jan 23 '14 at 07:13
  • @MELWIN, Some codes are compiler dependent. Always give details of your compiler while asking. Many people uses `GCC` and this code will not successfully compile on that. – Dipto Jan 23 '14 at 09:01
  • @Dipto should I include it in the question now??? – MELWIN Jan 23 '14 at 09:28
  • @MELWIN, its ok as you added the tag. – Dipto Jan 23 '14 at 09:29

3 Answers3

4

ASCII is a character-encoding scheme originally based on the English alphabet that encodes 128 specified characters. So yes, there are lots of keys in many keyboards having no ASCII code.

What you are referring to is closer to scancode. Some keys, for example function keys, have scancodes which do not have a printable representation ie. the code does not fall into [0-127]. The way function keys are interpreted depends heavily on your environment as well, for example is your terminal emulator running on VT100 mode or not.

  • But ESc, backspace enter ... etc also contain ascii values. and while i am pressing those The value is displayed also... – MELWIN Jan 23 '14 at 05:41
  • 2
    And when you press the function keys, it is possible that a control sequence is generated, quite possibly starting with an ESC character, or it may be treated differently. It's a tricky area, but there are lots of keys that are not ASCII. For example, the ellipsis … here was typed but is not an ASCII code. Ditto ™£¢∞§¶åß∂Îǃ etc. When I keep the 'fn' (function) key pressed and hit the F1 key, I get ESC O P generated. If I don't press the function key, the screen dims one notch. It depends on the hardware, and the O/S. – Jonathan Leffler Jan 23 '14 at 05:55
2

What happens with keys depends upon your terminal type/operating system. The general thing that happens is the following:

keyboard -> some sort of interrupt hook (part of the OS) -> change keystrokes to ASCII character -> provide the result to your program.

For example, the ASCII character for 'A' is 65, and for 'a' is 97. However, the physical key on the keyboard is the same. The ASCII character is the result of the way in which the operating system interprets the sequence/group of keys pressed.

For accessing the key pressed, you will have to do some low-level programming. Needless to mention, this will be operating-system specific.

ssm
  • 5,277
  • 1
  • 24
  • 42
2

It really depends on your standard lib (most likely from your compiler). As such what you will get will very from OS to OS and compiler to compiler.

Your standard lib takes the OS calls to read keys. It then converts the value returned from the OS to values that get returned from the C stdin. Some mappings are straightforward like A-Z but others like F1-F12, page up/down, and ALT-Keys are not.

There are a few things that most people agree on:

  • A-Z map to ASCII 65-90
  • a-z map to ASCII 97-122
  • 0-9 map to ASCII 48-57
  • Standard punctuation map to ASCII where they exist (.,"! etc)
  • Control A-Z map to ASCII control codes 1-26
  • Return/Enter maps to ASCII 13
  • ESC maps to ASCII 27
  • TAB maps to ASCII 9

Most times they agree on these as well:

  • Backspace maps to ASCII 8
  • Delete maps to ASCII 127

This is why you sometimes get a value for some keys but not all of them.

Based on your function call getche() and your tag turboc++, I suspect you are using Turbo C++. Turbo C++ uses the old DOS method (as does GWBasic and a lot of other programs from the DOS days).

In the DOS method you would get a 0 followed by a second character that was the key pressed. So you would read stdin, if it was 0 read stdin again, and then handle that code as the key pressed in a switch statement.

For example left arrow is "\0" followed by a "K".

Here are a number of common keys using the DOS method.

a=getche();
if(a==0)
{
   a=getche();
   switch(a)
   {
      case 'H': printf("Up arrow\n");break;
      case 'P': printf("Down arrow\n";break;
      case 'K': printf("Left arrow\n";break;
      case 'M': printf("Right arrow\n";break;
      case ';': printf("F1\n";break;
      case '<': printf("F2\n";break;
      case '=': printf("F3\n";break;
      case '>': printf("F4\n";break;
      case '?': printf("F5\n";break;
      case '@': printf("F6\n";break;
      case 'A': printf("F7\n";break;
      case 'B': printf("F8\n";break;
      case 'C': printf("F9\n";break;
      case 'D': printf("F10\n";break;
      case 133: printf("F11\n";break;
      case 134: printf("F12\n";break;
      case 'R': printf("Ins\n";break;
      case 'S': printf("Del\n";break;
      case 'G': printf("Home\n";break;
      case 'O': printf("End\n";break;
      case 'I': printf("PgUp\n";break;
      case 'Q': printf("PgDn\n";break;
      default:
         printf("Unknown\n");
   }
}
Paul Hutchinson
  • 1,578
  • 15
  • 21