Ссылка на массив const char *

Я пытаюсь избежать повторения моего кода для 5 разных массивов. У меня есть 3 массива (может быть больше в будущем):

const char *FirstlistOfOptionText[2]   = {OPT_1,
OPT_2};
const char *SecondlistOfOptionText[2]   = {OPT_1,
OPT_2};
const char *ThirdlistOfOptionText[2]  = {OPT_1,
OPT_2};

Элементы в каждом не будут одинаковыми. Теперь они потому что я просто копирую&вставьте их. Количество элементов не будет ни.

У меня есть функция, в которой я хочу напечатать каждый элемент списка в зависимости от значения, которое я задаю в качестве параметра. Кроме того, мне нужно напечатать один из этих элементов другим цветом (все в белом, кроме одного в зеленом).

Я просто хочу иметь один код для печати и выбора цвета, который у меня есть сейчас. Но я хочу выбрать правильный массив, прежде чем делать это. Я думал о:

const char *listOfOptions[];
if(menu_t.first_level_option == 0) {
listOfOptions = FirstlistOfOptionText;
}
if(menu_t.first_level_option == 1) {
listOfOptions = SecondlistOfOptionText;
}
if(menu_t.first_level_option == 2) {
listOfOptions = ThirdlistOfOptionText;
}

Но я получаю некоторые ошибки о размере хранилища listOfOptions, неизвестно. Или что я не могу использовать const char ** для char * или что-то в этом роде.

Как правильно это сделать?

2

Решение

По сути, вам нужно сделать listOfOptions char **;

Массив указателей можно ссылаться через указатель на указатели (это то, что символ **).

Размер будет неизвестен никому, использующему listOfOptions, поэтому вам нужен способ определить размер. Либо завершите список указателем NULL, либо вам придется использовать 2-ю переменную (listOfOptionsSize), которая отслеживает размер.

Поэтому приведенный ниже код должен скомпилироваться (я выбрал завершенные списки NULL).

const char *FirstlistOfOptionText[]   = {"a",  "b", NULL};
const char *SecondlistOfOptionText[]   = {"c", "d", "e", "f", NULL};
const char *ThirdlistOfOptionText[]  = {"e",  "f", "g", NULL};

const char **listOfOptions= NULL;  // pointer to pointer(s)
int first_level_option= 2;         // some value for testingif(first_level_option == 0) {
listOfOptions = FirstlistOfOptionText;
}
if(first_level_option == 1) {
listOfOptions = SecondlistOfOptionText;
}
if (first_level_option == 2) {
listOfOptions = ThirdlistOfOptionText;
}

printem(listOfOptions);

Теперь для вашей функции печати он получит указатель на список указателей в качестве параметра и будет выглядеть так:

void printem(const char **listOfOptions)
{
const char *word;

while (*listOfOptions!=NULL) {  // while the pointer in the list not NULL
word= *listOfOptions;        // get the char * to which listOfOptions is pointing
printf("entry: %s\n", word);
listOfOptions++;
}
}

О, и добро пожаловать в C-Pointer Hell 🙂

1

Другие решения

const char *FirstlistOfOptionText[2] массив двух указателей на символ

const char *listOfOptions[] массив неизвестного размера с указателями на символ

const char **listOfOptions; это указатель на указатель на символ, и вы можете назначить ему адрес вашего списка параметров массива:

listOfOptions = FirstlistOfOptionText;
1

const char *listOfOptions[];

Но я получаю некоторые ошибки о размере хранилища listOfOptions, неизвестно.

Размер массива является частью его типа. T[1] а также T[2] разные типы.

Массив без указанного размера является неполный тип, и вы не можете создать объект неполного типа.

Или что я не могу использовать const char ** для char * или что-то в этом роде.

Да, потому что это совершенно разные типы. Первый — указатель на указатель на константу char объект. Второй указатель на непостоянный char объект.

Ваш код пытается обработать массив как первоклассного гражданина, которого вы можете назначить как «нормальный» объект, такой как int, Он также пытается обрабатывать массивы разных размеров одинаково. Ничто из этого не может работать. Массивы C ++ более ограничены, чем вы думаете.


Таким образом, решение заключается в использовании std::vector, И пока вы на это, std::string вместо char*,

#include <string>
#include <vector>

#define OPT_1 "a"#define OPT_2 "b"
int main()
{
std::vector<std::string> FirstlistOfOptionText = { OPT_1, OPT_2 };
std::vector<std::string> SecondlistOfOptionText = { OPT_1, OPT_2 };
std::vector<std::string> ThirdlistOfOptionText = { OPT_1, OPT_2 };

int first_level_option = 0;

std::vector<std::string> listOfOptions;

if (first_level_option == 0) {
listOfOptions = FirstlistOfOptionText;
}
if (first_level_option == 1) {
listOfOptions = SecondlistOfOptionText;
}
if (first_level_option == 2) {
listOfOptions = ThirdlistOfOptionText;
}
}

Конечно, это можно (и нужно) улучшить еще больше. Например, избавиться от макросов препроцессора и поместить выбор списка в такую ​​функцию, как std::vector<std::string> GetListOfOptions(int),

0

Для печати списка опций вы можете использовать функцию шаблона, которая принимает ссылку на статический массив в качестве параметра:

template <int n>
void PrintOptions(const char* (&listOfOptions)[N])
{
for (int i = 0; i < N; i++)
{
//actual printing
}
}

void PrintMenu(/* ... */)
{
//...

switch (menu_t.first_level_option)
{
case 0:
PrintOptions(FirstlistOfOptionText);
break;
case 1:
PrintOptions(SecondlistOfOptionText);
break;
case 2:
PrintOptions(ThirdlistOfOptionText);
break;
}

//...
}

Размер массива будет определяться компилятором.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector