Структура, которая содержит массив массивов символов

DELETE FROM story_category
WHERE category_id NOT IN (
    SELECT cid FROM (
        SELECT DISTINCT category.id AS cid FROM category INNER JOIN story_category ON category_id=category.id
    ) AS c
)
2
задан StoryTeller 16 January 2019 в 08:06
поделиться

4 ответа

Один из вариантов будет:

struct widget_t {
    char const *name;
    uint8_t numberOfNicknames;
    char const * const *nicknames;
};

static char const *mower_nicknames[] = { "Choppie", "Bob" };
widget_t SomeWidget = { "Lawn Mower", 2, mower_nicknames };

static char const *bus_nicknames[] = { "Wheels", "Go", "Round" };
widget_t OtherWidget = { "Bus", 3, bus_nicknames };

// no setup function needed
0
ответ дан M.M 16 January 2019 в 08:06
поделиться

Здесь есть разные проблемы.

Сначала ваш последний член имеет неполный тип, потому что это массив необъявленного измерения. Это не разрешено в C ++, но большинство компиляторов допускает его как расширение с той же семантикой, что и в C. В любом случае, это довольно сложно использовать, поскольку его можно использовать только с выделенными структурами, где вы выделяете память для самой структуры и неполный массив.

Далее вы пытаетесь присвоить массиву. Ты не можешь. Массивы не являются объектами первого класса в C ++ (и в C). Вы можете инициализировать массив целиком, но можете назначить его только элементу массива.

И наконец, вы назначаете C литеральную строку для char *. Это плохо, потому что стандарт объявляет, что литеральные строки имеют значение const, поэтому использование более позднего указателя для изменения символа будет неопределенным поведением. Это сработает, если вы этого не сделаете, но указатели должны быть по крайней мере объявлены как const.

Вот как вы можете использовать все это:

widget_t* setUpFunction () {
    // allocates a widget_t with 2 slots in nicknames
    widget_t *someWidget = (widget_t *) malloc(sizeof(widget_t) + 2 * sizeof(char *));
    someWidget.name = (char *)"Lawn Mower";   // VERY DANGEROUS: pointer should be const
    someWidget.numberOfNicknames = 2;
    someWidget.nicknames[0] = (char *) "Choppie McGrasschopper"; // SAME DANGER
    someWidget.nicknames[1] = (char *) "Really Noisy"            // Still same danger
    return widget_t;
}

Но все это скорее C-ish и его следует избегать в C ++. Кроме того, он все еще требует выделенной памяти, что может не соответствовать тому, что вы хотите для Arduino

0
ответ дан Serge Ballesta 16 January 2019 в 08:06
поделиться

Что вы пытаетесь сделать, это назначить строковый литерал указателю char * - это плохо (подробнее см. Как избавиться от deprecated conversion from string constant to ‘char*’ предупреждений в GCC? ). Вот возможный подход:

#define MAX_NAME_LEN 128
#define MAX_NICK_NAMES 10

struct widget_t {
    char name[MAX_NAME_LEN];
    uint8_t numberOfNicknames;
    char nicknames[MAX_NICK_NAMES][MAX_NAME_LEN];
};

widget_t SomeWidget;

void setUpFunction () {
    strcpy(SomeWidget.name, "Lawn Mower");
    SomeWidget.numberOfNicknames = 2;
    strcpy(SomeWidget.nicknames[0], "Choppie McGrasschopper");
    strcpy(SomeWidget.nicknames[1], "Really Noisy");
}

В любом случае, поскольку вы пометите свой вопрос с помощью C++, я бы предложил вам использовать вместо этого std::string и std::vector.

0
ответ дан duong_dajgja 16 January 2019 в 08:06
поделиться

Ваша проблема в том, что c ++ не поддерживает переменные массивы. Вместо этого вам придется динамически распределять память, используя new или в вашем случае new [] .

Сначала вам нужно изменить тип данных на char**, почти равный предыдущему. Затем вы можете выделить столько строк, сколько захотите nicknames = new char*[number_of_nicknames].

Важно то, что с помощью этого метода вам придется вручную добавлять свои псевдонимы следующим образом: delete[] nicknames;. Лучший способ сделать это - использовать RAII (удалить ваши псевдонимы в деконструкторе)

Если у вас есть динамические строки, вы бы использовали следующую структуру

struct widget_t {
    // optional constructor to allocate nicknames

    ~widget_t()
    {
        for (int i = 0; i < numberOfNicknames; ++i)
        {
            char* nickname = nicknames[i];

            if (nickname)
                delete[] nickname;
        }

        delete[] nicknames;
    }

    char *name;
    uint8_t numberOfNicknames;
    char **nicknames = NULL;
};

и с постоянной строкой следующий

struct widget_t {
    // optional constructor to allocate nicknames
    // allocate nicknames like
    // -> nicknames = new const char*[numberOfNicknames];

    ~widget_t()
    {
         if (nicknames) delete[] nicknames;
    }

    char *name;
    uint8_t numberOfNicknames;
    const char **nicknames = NULL;
};
0
ответ дан Phins 16 January 2019 в 08:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: