C中的二维数组字符串

时间:2015-09-03 20:57:39

标签: c arrays

我在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_menuother_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),其中内存非常稀缺,所以我不想声明大于必要的数组,从而浪费内存。有什么我可以做的,或者这是否尽可能简单?

3 个答案:

答案 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][...],它同样可以接受。