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