Как инициализировать этот массив структур из массива структур? - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть следующий код, который не работает, как ожидалось.Он компилируется, но выдает много предупреждений и ошибок при выполнении:

#include <stdio.h>

enum output {
    A,
    B,
    C,
    D,
};

struct translation {
    char *from;
    enum output to;
};

struct dictionary {
    struct translation *foo;
    struct translation *bar;
};

enum language {
    ONE,
    ANOTHER,
};

struct dictionary languages[] = {
        [ONE] = {
                .foo = {
                        {"LF", A},
                        {"LLF", C},
                        {"RRF", D},
                },
                .bar = {
                        {"L", B},
                },
        },
        [ANOTHER] = {
                .foo = {
                        {"FF", B},
                        {"RRF", D},
                },
                .bar = {
                        {"LF", B},
                        {"R", C},
                        {"RR", D},
                },
        },
};

int main(void)
{
        printf("%s\n", languages[ONE].foo[0].from);
        return 0;
}

Я, вероятно, неправильно инициализирую languages.

  • Я хотел бы получить это *Массив 1008 *, в котором я могу получить доступ к различным словарям с помощью language: languages[ONE]
  • Я хотел бы получить доступ к различным таблицам перевода с полем словаря: languages[ONE].foo
  • Все таблицы переводадоступ к паре язык + поле может иметь разную длину массива, как показано в примере кода

Возможно ли это?Что я делаю не так?

При компиляции с gcc я получаю (обрезанный) вывод:

asdf.c:27:17: warning: braces around scalar initializer
                 .foo = {
                 ^
asdf.c:27:17: note: (near initialization for ‘languages[0].foo’)
asdf.c:28:25: warning: braces around scalar initializer
                         {"LF", A},
                         ^
asdf.c:28:25: note: (near initialization for ‘languages[0].foo’)
asdf.c:28:26: warning: initialization of ‘struct translation *’ from incompatible pointer type ‘char *’ [-Wincompatible-pointer-types]

[...]

Одинаковые предупреждения / примечания повторяются для нескольких частей кода.

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Просто инициализируйте каждый массив отдельно:

#include <stdio.h>

enum output
{
    a
,   b
,   c
,   d
};

struct translation
{
    char const * from;
    enum output  to;
};

struct dictionary
{
    struct translation * foo;
    struct translation * bar;
};

enum language
{
    one
,   another
,   languages_count
};

struct translation one_language_foo_translations[] =
{
    {"LF" , a}
,   {"LLF", c}
,   {"RRF", d}
};

struct translation one_language_bar_translations[] =
{
    {"L", b}
};

struct translation another_language_foo_translations[] =
{
    {"FF" , b}
,   {"RRF", d}
};

struct translation another_language_bar_translations[] =
{
    {"LF", b}
,   {"R" , c}
,   {"RR", d}
};

struct dictionary languages[languages_count] =
{
    {one_language_foo_translations, one_language_bar_translations}
,   {another_language_foo_translations, another_language_bar_translations}
};

int main(void)
{
    printf("%s\n", languages[one].foo[0].from);
    return 0;
}

онлайн-компилятор

0 голосов
/ 20 ноября 2018

Вот две вещи, которые вы можете сделать:

  1. Выделить память для struct translation *foo; и struct translation *bar; (вы также можете использовать malloc для динамического выделения памяти).Например:
struct dictionary
{
    struct translation foo[10];
    struct translation bar[10];
};
Используйте составной литерал в своем определении:
struct dictionary languages[] = {
    [ONE] = {
            .foo = (struct translation []){
                    {"LF", A},
                    {"LLF", C},
                    {"RRF", D},
            },
            .bar = (struct translation []){
                    {"L", B},
            },
    },
    [ANOTHER] = {
            .foo = (struct translation []){
                    {"FF", B},
                    {"RRF", D},
            },
            .bar = (struct translation []){
                    {"LF", B},
                    {"R", C},
                    {"RR", D},
            },
    },
};

Примечание

Как указано @ MM , добавивКвалификатор const перед struct dictionary - хорошая идея, если его значения не изменятся во время выполнения.

...