Thread: Creating a C menu using Up Down

  1. #1
    Registered User
    Join Date
    Feb 2011
    Location
    Trinidad and Tobago
    Posts
    2

    Question Creating a C menu using Up Down

    Hey guys,
    Basically this code creates a menu and the user uses the up,down keyboard keys to move throughout the menu.
    Can anyone tell me why is this code giving the output in the picture (using Turbo C++ book code):

    Code:
    /* menu.c*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #define TRUE 1
    #define NUM 5
    #define CLEAR "\x1B[2J"
    #define ERASE "\x1B[K"
    #define NORMAL "\x1B[0m"
    #define REVERSE "\x1B[7m"
    #define HOME "\x1B[1;1f"
    #define BOTTOM "\x1B[20;1f"
    #define U_ARRO 72
    #define D_ARRO 80
    #define INSERT 82
    void action(int);
    char getcode(void);
    void display(char *arr[], int size, int pos);
    
    int main (void){
        
        static char *items[NUM] =
               { "Open",
                 "Close",
                 "Save",
                 "Print",
                 "Quit", };
                 
    int curpos;
    printf(CLEAR);
    curpos=0;
    
    while(TRUE){
                display(items,NUM,curpos);
                switch (getcode()){
                       case U_ARRO:
                            if(curpos>0) --curpos; break;
                       case D_ARRO:
                            if(curpos<NUM-1) ++curpos; break;
                       case '\r':
                            action(curpos); break;
                            }
                }
                return 0;
    }
    /*display()*/
    void display(char *arr[], int size, int pos){
    int j;
    
    printf(HOME);
    for(j=0; j<size; j++){
             if(j==pos) printf(REVERSE);
             printf("%s\n",*(arr+j));
             printf(NORMAL);
             }
             
    printf(BOTTOM);
    }
    
    /*getcode*/
    /*gets keyboard code*/
    char getcode(void){
         int key;
         
         if( (key=getch()) == 0)
         return ( getch() );
         else if (key == '\r')
         return (key);
         else return (0);
         }
    
    /*action()*/
    /*Performs action based on cursor position*/
    void action(int pos){
         printf(ERASE);
         switch(pos){
                     case 0:
                     printf("Open"); break;
                     case 1:
                     printf("Close"); break;
                     case 2:
                     printf("Save"); break;
                     case 3:
                     printf("Print"); break;
                     case 4:
                     exit(0);
                     }
                     
    }
    Output:
    http://img690.imageshack.us/img690/304/10244632.jpg
    Last edited by Salem; 02-26-2011 at 03:30 PM. Reason: Use the proper code tags!!!!!

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Several of the defined keys rely on the system using ansi.sys, which was very common in DOS days, but not so much nowadays. My suggestion is to replace them, with either keyboard scan codes, or Windows equivalent way of doing it.

    The basic program looks OK, but the define keys are ready for the bin.

    If you don't have a table of the PC key scan values, Google has dozens of sites with them. If you want to use the Windows version, goto the MSDN library and they explain it all and give an example of their (typically somewhat more complicated), way of handling it.

  3. #3
    Third Eye Babkockdood's Avatar
    Join Date
    Apr 2010
    Posts
    352
    Those are some funky-ass strings. I recommend looking at the pdcurses library. It's a port of the curses library for Windows (it looks like you're using Windows - if you're not, you can just uses curses).
    Quote Originally Posted by The Jargon File
    Microsoft Windows - A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    I could tell you to stop digging for fossils and upgrade to a compiler for this millenium.

    Code::Blocks
    smorgasbordet - Pelles C

    See, if we help you with TurboCrap, it only prolongs it's agonising death. Only when tutors finally figure out there is no longer any free tech support on the web will they stop pushing this old crap on people.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Feb 2011
    Location
    Trinidad and Tobago
    Posts
    2
    Thanks guys for the help i've gotten piece to work. Still trying to figure out the rest. p.s i am using DEV C++ to do all my programming.

    Quote Originally Posted by Salem View Post
    I could tell you to stop digging for fossils and upgrade to a compiler for this millenium.

    Code::Blocks
    smorgasbordet - Pelles C

    See, if we help you with TurboCrap, it only prolongs it's agonising death. Only when tutors finally figure out there is no longer any free tech support on the web will they stop pushing this old crap on people.
    You're right but i'm not doing turbo C lol i used a Turbo C book as reference for a menu i was making... but i wasn't sure what i could do to make it not show those random chars. I was hoping someone can do a cross reference to the #define constants.
    i.e instead of #define CLEAR "\x1B[2J" use #define CLEAR "example" ... something like that.

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Those escape codes handle things like clearing the screen, switching color sets, etc. (See: ANSI escape code - Wikipedia, the free encyclopedia) The reason we can't just say "instead of X use Y" is because the functions that would handle that are all compiler / OS specific. There isn't any way to say... make yellow text on a blue background.


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Here's a version for you, that does what you want.

    Don't tell Quzah about the yellow text on a blue background output, because he gets really grumpy when he thinks he knows it all, and finds out he really doesn't.

    Note how some keys give off more than one value, so if the first value is a zero, it uses the second value.

    Code:
    #include <stdio.h>
    
    #define ESC 27
    #define F1 59
    #define F2 60
    #define F3 61
    #define F4 62
    #define F5 63
    #define F6 64
    #define F7 65
    #define F8 66
    #define F9 67
    #define F10 68
    #define HOME 71
    #define UP 72
    #define PAGE_UP 73
    #define LEFT 75
    #define RIGHT 77
    #define END 79
    #define DOWN 80
    #define PAGE_DOWN 81
    
    int main(void) {
    
      char key;
      char msg[20];
      textbackground(1);
      textcolor(14);
      printf("\n\n\t\t\t     press escape to quit\n\n") ;
      do {
        key = getch();
        if (key == 0) {
          key = getch(); //key code has two keys - read the second one
          switch (key) {
            case F1: memcpy(msg,"F1", sizeof(msg)); break;
            case F2: memcpy(msg,"F2", sizeof(msg)); break;
            case F3: memcpy(msg,"F3", sizeof(msg)); break;
            case F4: memcpy(msg,"F4", sizeof(msg)); break;
            case F5: memcpy(msg,"F5", sizeof(msg)); break;
            case F6: memcpy(msg,"F6", sizeof(msg)); break;
            case F7: memcpy(msg,"F7", sizeof(msg)); break;
            case F8: memcpy(msg,"F8", sizeof(msg)); break;
            case F9: memcpy(msg,"F9", sizeof(msg)); break;
            case F10: memcpy(msg,"F10", sizeof(msg)); break;
            case PAGE_UP: memcpy(msg,"PAGE UP", sizeof(msg)); break;
            case PAGE_DOWN: memcpy(msg,"PAGE DOWN", sizeof(msg)); break;
            case HOME: memcpy(msg,"HOME", sizeof(msg)); break;
            case END: memcpy(msg,"END", sizeof(msg)); break;
            case UP: memcpy(msg,"UP", sizeof(msg)); break;
            case DOWN: memcpy(msg,"DOWN", sizeof(msg)); break;
            case LEFT: memcpy(msg,"LEFT", sizeof(msg)); break;
            case RIGHT: memcpy(msg,"RIGHT", sizeof(msg)); break;
            default:  memcpy(msg,"unknown key", sizeof(msg)); break;
          }
          cprintf("Key: %s", msg);
          putchar('\n');
          continue;
        }
        if(key == ESC) {
          cprintf("Key: ESCAPE");
          putchar('\n');
        }
        else {
          cprintf("Key: %c", key);
          putchar('\n');
        }
      }while (key != ESC); 
    
      printf("\n\n\t\t\t     press enter when ready");
      (void) getchar();  //hold the console window open
      return 0;
    }
    You can't compile this unless you have a non standard compiler extension, that smartly links in the needed header. One like RockLee has.

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Since he's using DevC++, he'll need this: The Dev-C++ Resource Site


    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 03-05-2009, 10:25 AM
  2. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  3. Profiler Valgrind
    By afflictedd2 in forum C++ Programming
    Replies: 4
    Last Post: 07-18-2008, 09:38 AM
  4. Creating a menu system
    By ICool in forum C Programming
    Replies: 9
    Last Post: 09-17-2007, 12:18 PM

Tags for this Thread