2016-10-08 2 views
2

Я стараюсь не повторять свой код для 5 различных массивов. У меня есть 3 массивы (может быть больше в будущем):Рецензия на const char * array

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 * или подобной вещи.

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

+3

«... код для 5 различных массивов. У меня есть 3 массива ...» 5? 3? это немного запутывает – user463035818

+1

Просьба указать [mcve] и точное сообщение об ошибке. «некоторые ошибки» и «или что-то вроде этого» слишком неспецифичны, чтобы угадать, что происходит не так. – user463035818

+3

Используете ли вы C или C++? –

ответ

1

По сути вы сделать нужду listOfOptions полукокса **;

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

Размер будет неизвестен любому, использующему listOfOptions, таким образом, вам нужен способ определить размер. Либо завершите список указателем NULL, либо вам придется использовать вторую переменную (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 testing 


if(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 ад: -)

+0

Я пробовал вашу инициализацию, и я получаю эту ошибку: ошибка: слишком много инициализаторов для 'const char * [0] – user1298272

+0

Я забыл обновить. Я заработал. Я просто удаляю последний элемент NULL и задаю размер каждого массива. У меня нет проблем с этим, потому что у меня есть переменная, содержащая размер каждого массива. Спасибо! – user1298272

+0

рад слышать, что – Anachronism

1

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

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

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

listOfOptions = FirstlistOfOptionText; 
0
const char *listOfOptions[]; 

But I get some errors about storage size of 'listOfOptions' isn't known.

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

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

Or that I can't use const char** for a char* or thing like that.

Да, потому что это совершенно разные типы. Первый - это указатель на указатель на постоянный объект 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; 
    } 

    //... 
} 

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

Смежные вопросы