2012-05-13 10 views
5

Próbuję stworzyć prosty program w C, gdzie użytkownik ma do wyboru między kilkoma opcjami:Jak napisać menu konsoli w ANSI/ISO C?

char command = '1'; 
while(command!='0') { 
    printf("Menu:\n"); 
    printf("1. First option\n"); 
    printf("2. Second option\n"); 
    printf("0. Exit\n"); 
    printf("Choose: 0,1,2?: "); 
    command = getchar(); 
    while(getchar()!='\n');  
    switch(command) { 
     case '0': break; 
     case '1': functionCall1(); break; 
     case '2': functionCall2(); break; 
    } 
} 

Problem z mojego kodu jest, że każdy drugi raz wejść 1,2 lub 0, nic się nie dzieje, tylko menu ponownie się drukuje. Z debuggerem widzę, że wartość komenda, po poleceniu = getchar() jest równa "", co drugi raz. Myślałem, że jedzenie nowej postaci jest wystarczające?

+2

Twój przykład działa OK dla mnie, jak jest, i jeśli mam functionCall1 i functionCall2 druku coś widzę, że działa jak reklamowane. Ale może jest inaczej z twoim kompilatorem? –

+3

Typ 'polecenia' musi mieć postać' int', a nie 'char', aby móc przytrzymywać' EOF'. Zauważ, że kiedy ktoś wchodzi do EOF (na przykład Ctrl-D na Uniksie), twój program obraca się w pętli 'while (getchar()! = '\ N');'. – Jens

+2

a 'do {...} while ('0'! = Command);' byłoby bardziej eleganckim konstruktem – guga

Odpowiedz

1

Może powinieneś spróbować użyć int x jako klucz do korzystania pożądany polecenie, może być tak:

while(x != 0) 
{ 
    scanf("%d", &x); 
    switch (x) 
    { 
     printf("input '2' to...\n"); 
     printf("input '3' to...\n"); 
     printf("input '4' to...\n"); 
     printf("input '5' to...\n"); 
     printf("input '6' to...\n"); 
     case 1: 
      head = Enqueue(head); 
      break; 
     case 2: 
      head1 = spisokMagazinovScenoiMensheiZadannoi(head, head1); 
      break; 
     case 3: 
      head1 = udalenieElementa(head1); 
      break; 
     case 4: 
      head1 = addNewMagazin(head1); 
      break; 
     case 5: 
      head1 = addNewMagazin(head1); 
      break; 
     case 6: 
      printToTheFile(head); 
      break; 

    } 
} 

użyłem go w mojej poprzedniej lekcji. Mam nadzieję, że będzie użyteczne dla ciebie

3

Wypróbuj moje dostosowane menu, zaimplementowałem je, aby moje życie było łatwiejsze, gdy pracuję z programami, które zawiera wiele operacji wyboru. Menu jest spławne (strzałki: góra, dół, lewo, prawo), a do selekcji wystarczy nacisnąć klawisz Enter, orientacja menu może być ustawiona pionowo lub poziomo, dopełnienie można ustawić na grupę przedmiotów (dzieci) , pozycja początkowa dziecka i aktualizacja z opóźnieniem.

przykład wywołanie menu (w pionie):

int response = menu("OPTIONS","[*]","->", 
        1,3,3,0,5, 
        "PROFILES","ACTIVITY","VIDEO","SOUND","GAMEPLAY"); 

Najważniejszą rzeczą jest to, ponieważ realizacja funkcji zajmuje tylko 60 linii kodu.

realizacja Menu:

#include <stdio.h> 
#include <stdlib.h> 
#include <stdarg.h> 
#include <windows.h> 

// LXSoft 
// mod: cui/menu_021 
// stdarg.h -> used for variable list of arguments (va_list, va_start ...) 
// windows.h -> used for Sleep function, for *nix use unistd.h 

typedef unsigned short int usint_t; 
// Menu function prototype 
int menu(char* name, char* prefix, char* cursor, usint_t orientation, 
     usint_t padding, usint_t start_pos, usint_t delay, 
     usint_t num_childs, ...); 

int main() 
{ 
    int response = menu("OPTIONS","[*]","->",1,3,3,0,5, 
         "PROFILES","ACTIVITY","VIDEO","SOUND","GAMEPLAY"); 
    switch(response) 
    { 
     case 1: 
      // doSomethingFoo1(); 
     break; 
     case 2: 
      //doSomethingFoo2(); 
     break; 
     /* 
     * . 
     * . 
     * . 
     * case n: 
     * break; 
     */ 
    } 
    printf("\nYour choice is: %d", response); 
    return 0; 
} 

// Menu implementation 
int menu 
(
    char *name,  // Menu name (eg.: OPTIONS) 
    char *prefix,  // Menu prefix (eg.: [*]) 
    char *cursor,  // Menu cursor (eg.: ->) 
    usint_t orient, /* 
         * Menu orientation vertical or horzontal. 
         * 0 or false for horizontal 
         * 1 or true for vertical 
         */ 
    usint_t padding, // Menu childrens padding (eg.: 3) 
    usint_t start_pos, // Menu set active child (eg.: 1) 
    usint_t delay,  // Menu children switch delay 
    usint_t childs, // Number of childrens 
    ...    /* 
         * Variable list of arguments char* type. 
         * Name of the childrens. 
         */ 
) 
{ 
    va_list args; 
    int tmp=0,pos; 
    char chr; 
    usint_t opt=start_pos; 
    char* format=malloc 
    (
     (
      strlen(name)+strlen(prefix)+strlen(cursor)+ 
      3+ /* menu suffix (1 byte) and backspace (2 bytes) */ 
      (2*childs)+ /* newline (2 bytes) times childs */ 
      (padding*childs)+ /* number of spaces times childs */ 
      childs*15 /* children name maxlen (15 bytes) times childs*/ 
     )*sizeof(char) 
    ); 
    do 
    { 
     if(tmp!=0)chr=getch(); 
     if(chr==0x48||chr==0x4B) 
      (opt>1&&opt!=1)?opt--:(opt=childs); 
     else if(chr==0x50||chr==0x4D) 
      (opt>=1&&opt!=childs)?opt++:(opt=1); 
     else {/* do nothing at this time*/} 
     strcpy(format,""); 
     strcat(format,prefix); 
     strcat(format,name); 
     strcat(format,":"); 
     va_start(args,childs); 
     for (tmp=1;tmp<=childs;tmp++) 
     { 
      (orient)?strcat(format,"\n"):0; 
      pos=padding; 
      while((pos--)>0) strcat(format," "); 
      if(tmp==opt) 
      { 
       strcat(format,"\b"); 
       strcat(format,cursor); 
      } 
      strcat(format,va_arg(args,char*)); 
     } 
     /*if(tmp!=childs) 
     { 
      fprintf(stderr,"%s: recieved NULL pointer argument," 
          " child not named", __func__); 
      return -1; 
     }*/ 
     Sleep(delay); 
     system("cls"); 
     printf(format); 
     va_end(args); 
    }while((chr=getch())!=0x0D); 
    return opt; 
} 
+0

bardzo ładne! zasłużyć na naukę realizacji. –