C format string

103 Views Asked by At

I have problem in this code. This is behaving so weirdly. please explain.

printf("CONTROLS:\nw , %c: up\n" 
        "a , %c: left\n" 
        "s , %c: down\n" 
        "d , %c: right\n" 
        "q , ESC: EXIT\n"
        ,24,27,25,26);

OUTPUT:

CONTROLS:
w , ↑: up
a ,  left
s , ↓: down
d , →: right
q , ESC: EXIT

I tried removing the colon after %c but it eats the 'l'

what is happening. I am interested in knowing the behind the scenes.

//this works:
 for(int ch=24;ch < 28;ch++) /* 27 = Esc key */
    {
        printf("%c:%d\n",ch,ch);

    }

2

There are 2 best solutions below

2
greg spears On

Your original code doesn't work out for a few reasons, but most notably because the printf() formatting is using %c ( for char ) and the codes ( 24, 27, 25, 26 ) given to the %c references in printf() do not align with the symbols you desire.

Here is some code that should work for you. It uses Unicode strings to get the results you want. Please also note the printf() formatting in this instance: we use %s for strings instead of %c -- which is used for chars.

This code actually gives the output shown below, and the runnable version is here.

EDIT: In appreciation of John Bollinger's comment below -- and always finding better ways of doing things -- please note the code update for the szUP declaration: it uses the newer/proper Unicode coding now. The results are in fact, identical and the runnable code is here.

#include <stdio.h>
#if 0
  char szUP[] = {0xE2, 0x86, 0x91, 0x00};
#else
  const char * const szUP = "\u2191";  /* Thx John B. */
#endif 
char szLT[] = {0xE2, 0x86, 0x90, 0x00};
char szDN[] = {0xE2, 0x86, 0x93, 0x00};
char szRT[] = {0xE2, 0x86, 0x92, 0x00};

int main()
{
printf("CONTROLS:\n"
        "w, %s: up\n" 
        "a, %s: left\n" 
        "s, %s: down\n" 
        "d, %s: right\n" 
        "q, ESC: EXIT\n",szUP,szLT,szDN,szRT);

    return 0;
}

Output:

    w, ↑: up
    a, ←: left
    s, ↓: down
    d, →: right
    q, ESC: EXIT
11
ikegami On

You are printing non-printable control characters. No glyphs are associated with those characters. They are meant to control the communication for various purposes, not to generate a glyph.

Now, your terminal happens to display arrows for some of the control characters it doesn't care about. But 271B in hex—is actually meaningful to the terminal. It's used as the start of sequences that clear the screen, move the cursor, color the screen, etc.

Long story short, you are using the wrong Code Points. You are using

  • U+0018 CANCEL
  • U+0019 END OF MEDIUM
  • U+001A SUBSTITUTE
  • U+001B ESCAPE

There are Code Points that produce arrow glyphs, including

  • U+2190 LEFTWARDS ARROW (←)
  • U+2191 UPWARDS ARROW (↑)
  • U+2192 RIGHTWARDS ARROW (→)
  • U+2193 DOWNWARDS ARROW (↓)

You'll have to encode those appropriately for your terminal. That's probably UTF-8, so

  • U+2190 LEFTWARDS ARROW (←): E2 86 90
  • U+2191 UPWARDS ARROW (↑): E2 86 91
  • U+2192 RIGHTWARDS ARROW (→): E2 86 92
  • U+2193 DOWNWARDS ARROW (↓): E2 86 93