我在C中创建一个将使用文本菜单的应用程序。所以,我决定创建一个包含所有菜单的全局数组。作为稍后我将提到的问题的解决方法,代码如下所示:
char* main_menu[]=
{"Refresh rate", "Help", "Default config", NULL};
char* other_stuff[]=
{"Stuff", "More", NULL};
char** screens[]={main_menu, other_stuff};
我可以使用这些字符串:screens[0][1]
在第0个/第一个菜单中首先表示(或者说第二个,因为我们从零开始计算)选项。
它有效,但它让我觉得非常不优雅,我必须声明那些辅助数组(main_menu
和other_stuff
)。我试图利用数组的嵌套大括号初始化,但总是编译器会抱怨。此外,在你建议将数组声明为char* screeens[10][5]
之前 - 应该没有神奇的数字,因为这对我来说同样不优雅。
我试过了:
char** screens[]={
{"Refresh rate", "Help", "Default config", NULL},
{"Stuff", "More", NULL}
};
然而,编译器给了我一个警告(正确地说,因为访问元素会产生乱码):
../main.c:96:1: warning: braces around scalar initializer [enabled by default]
{"Refresh rate", "Help", "Default config", NULL},
^
../main.c:96:1: warning: (near initialization for ‘screens[0]’) [enabled by default]
../main.c:96:1: warning: initialization from incompatible pointer type [enabled by default]
../main.c:96:1: warning: (near initialization for ‘screens[0]’) [enabled by default]
../main.c:96:1: warning: excess elements in scalar initializer [enabled by default]
等等。
如果我将第一行更改为char* screens[][]={
,编译器根本不会编译代码,给出错误:error: array type has incomplete element type
。
我正在编写嵌入式环境(avr-gcc 4.8.1),其中内存非常稀缺,所以我不想声明大于必要的数组,从而浪费内存。有什么我可以做的,或者这是否尽可能简单?
答案 0 :(得分:6)
假设你有C99或更高版本,你可以使用'复合文字'初始化你的数组:
#include <stddef.h> // NULL
char **screens2[] =
{
(char *[]){ "Refresh rate", "Help", "Default config", NULL },
(char *[]){ "Stuff", "More", NULL },
};
或者,如果你想成为const
- 正确(一件好事 - 感谢M.M和他的comment):
char const * const * screens3[] =
{
(char const * const []){ "Refresh rate", "Help", "Default config", NULL },
(char const * const []){ "Stuff", "More", NULL },
};
编译(清除 - 没有警告或错误):
gcc -std=c11 -O3 -g -Wall -Wextra -Werror -pedantic -c 2das.c
(Mac OS X 10.10.5上的GCC 5.1.0)
答案 1 :(得分:0)
我在C中创建一个将使用文本菜单的应用程序。
您可以尝试这样的事情:
#include <stdio.h>
#include<unistd.h>
typedef int (*menu)(void);
void clearScreen(int x){
int i=0;
for(;i<x;i++){
printf("\n");
}
}
int exitMenu(void) {
clearScreen(100);
printf("Exiting... Goodbye\n");
sleep(1);
return 0;
}
int mainMenu(void){
clearScreen(100);
printf("\t\t\tMain Manu\n");
return 0;
}
int updateSystem(void) {
clearScreen(100);
printf("System update...\n");
sleep(1);
return 1;
}
int installVlcFromPpa(void) {
clearScreen(100);
printf("Install VLC from PPA \n");
sleep(1);
return 0;
}
int installVlcFromSource(void) {
clearScreen(100);
printf("Install VLC from Source \n");
sleep(1);
return 0;
}
int uninstallVLC(void) {
clearScreen(100);
printf("Uninstall VLC... \n");
sleep(1);
return 1;
}
int chooseOption(int min, int max){
int option,check;
char c;
do{
printf("Choose an Option:\t");
if(scanf("%d%c",&option,&c) == 0 || c != '\n'){
while((check = getchar()) != 0 && check != '\n');
printf("\tThe option has to be between %d and %d\n\n",min,max);
}else if(option < min || option > max){
printf("\tThe option has to be between %d and %d\n\n",min,max);
}else{
break;
}
}while(1);
return option;
}
void showMenu(char *question, char **options, menu *actions, int length) {
int choose = 0;
int repeat = 1;
int i;
menu act;
do {
printf("\n\t %s \n", question);
for(i = 0; i < length; i++) {
printf("%d. %s\n", (i+1), options[i]);
}
choose = chooseOption(1,length);
printf(" \n");
act = actions[choose - 1];
repeat = act();
if(choose == 3){
repeat = 0;
}
}while(repeat == 1);
}
int installVLC(void) {
clearScreen(100);
char *question = "Installing VLC from:";
char *options[10] = {"PPA", "Source", "Back to VLC menu"};
menu actions[3] = {installVlcFromPpa, installVlcFromSource, mainMenu};
showMenu(question, options, actions, 3);
return 1;
}
int meniuVLC(void) {
clearScreen(100);
char *question = "VLC Options";
char *options[10] = {"Install VLC.", "Uninstall VLC.", "Back to Menu."};
menu actions[3] = {installVLC, uninstallVLC, mainMenu};
showMenu(question, options, actions, 3);
return 1;
}
void startMenu(void){
clearScreen(100);
char *question = "Choose a Menu:";
char *options[10] = {"Update system.", "Install VLC", "Quit"};
menu actions[3] = {updateSystem, meniuVLC, exitMenu};
showMenu(question, options, actions, 3);
}
int main(void){
startMenu();
return 0;
}
Choose a Menu: 1. Update system. 2. Install VLC 3. Quit Choose an Option:
答案 2 :(得分:-2)
最优雅的方法是将它们声明为单独的变量
你也可以使用第一种方法但是使用枚举/定义,这样你就可以screens[MAIN_MENU][...]
而不是一些魔法screens[0xcafebabe][...]
,它同样可以接受。