2012-05-13 48 views
5

Tôi đang cố gắng để tạo ra một chương trình đơn giản trong c, nơi người dùng phải lựa chọn giữa một số tùy chọn:Làm thế nào để viết một giao diện điều khiển menu trong 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; 
    } 
} 

Vấn đề với mã của tôi là, rằng mỗi lần thứ hai tôi nhập 1,2 hoặc 0, không có gì xảy ra, chỉ có trình đơn tự in lại. Với trình gỡ rối tôi có thể thấy, giá trị của lệnh, sau lệnh = getchar() bằng '', mỗi lần thứ hai. Tôi nghĩ rằng ăn nhân vật mới là đủ?

+2

dụ của bạn chạy OK đối với tôi như là, và nếu tôi có functionCall1 và functionCall2 in một cái gì đó, tôi có thể thấy rằng nó hoạt động như quảng cáo. Nhưng có lẽ nó khác với trình biên dịch của bạn? –

+3

Loại 'lệnh' phải là' int' không 'char', để có thể giữ' EOF'. Lưu ý rằng khi ai đó nhập EOF (ví dụ: Ctrl-D trên Unix), chương trình của bạn sẽ quay trong vòng lặp 'while (getchar()! = '\ N');'. – Jens

+2

một 'do {...} trong khi ('0'! = Lệnh);' sẽ là một cấu trúc thanh lịch hơn – guga

Trả lời

1

Có thể là bạn nên cố gắng sử dụng int x như một chìa khóa để sử dụng một lệnh mong muốn, có thể là như thế:

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; 

    } 
} 

tôi đã sử dụng nó trong bài tập về nhà trước đây của tôi. Hy vọng nó sẽ hữu ích cho bạn

3

Hãy thử thực đơn tùy chỉnh của tôi, tôi đã thực hiện nó để làm cho cuộc sống của tôi dễ dàng hơn khi tôi làm việc với các chương trình có chứa nhiều thao tác lựa chọn. Menu có thể điều hướng (mũi tên: lên, xuống, sang trái, phải) và để thực hiện lựa chọn bạn chỉ cần nhấn phím enter, hướng menu có thể được đặt theo chiều dọc hoặc chiều ngang, có thể đặt thành một nhóm mục (childrens) , vị trí bắt đầu con và cập nhật với độ trễ.

menu gọi ví dụ (theo chiều dọc):

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

Điều quan trọng nhất là vì thực hiện chức năng chỉ mất 60 dòng mã.

đơn thực hiện:

#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

rất đẹp! xứng đáng học cách triển khai. –

Các vấn đề liên quan