Массив строк -- как правильно реализовать ?

Все о микроконтроллерах: AVR, PIC, STM8, STM32, Arduino, Altera, Xilinx, все что угодно. Этот раздел для всего что клацает байтиками.
abigsam
Сообщения: 11
Откуда: Сумы

Сообщение abigsam » 05 янв 2014, 22:28

Прошу у сообщества оказать посильную помощь :)
Есть некоторая функция comparestr (), которая в качестве аргументов принимает два указателя на строки. Если входные строки одинаковы -- возвращает ноль. Для наглядности:

Код: Выделить всё

error = comparestr (&COMMANDS, &buffer);

Хочу вместо COMMANDS скармливать функции массив строк, вот так:

Код: Выделить всё

 while (i <= 6)
      {
         error = comparestr (COMMANDS[i], &buffer);
         if (error == 0) break;
         i++;
      }

Вопрос: как правильно описать такой массив ? Как правильно прописать аргумент функции ?
Сейчас описываю массив так:

Код: Выделить всё

/*Constants-------------------------------------- */
//-------------- Команды ---------------
const uint8_t SET_TIME[]            = "settime\r";
const uint8_t SET_TELEPHONE[]  = "settelephone\r";
const uint8_t SET_NUMBER[]       = "setnum\r";
const uint8_t SET_SCHEDULE[]    = "setschedule\r";
const uint8_t SHOW_SETTINGS[] = "showsettings\r";
const uint8_t SAVE_SETTINGS[]   = "save\r";

const uint8_t *COMMANDS[6] = {SET_TIME,
                   SET_TELEPHONE,
                   SET_NUMBER,
                   SET_SCHEDULE,
                   SHOW_SETTINGS,
                   SAVE_SETTINGS};

Выражением *COMMANDS[6] я делаю массив указателей, каждой ячейке массива присваиваю значение указателей на строки. Но компилятор пишет, что "несовместимый тип аргумента" для функции comparestr ().
Заранее благодарю :)

P.S. Использую STVD + Cosmic
Последний раз редактировалось abigsam 06 янв 2014, 00:05, всего редактировалось 3 раза.

Аватара пользователя
N1X
Сообщения: 321
Откуда: Беларусь, Гомель

Сообщение N1X » 05 янв 2014, 23:49

Это вытянуто из исходника? Ибо у вас в вызове COMMAND[i], а объявлен и определен массив COMMANDS[6]... Других проблем беглым взглядом не увидел ) При таком объявлении действительно массив указателей, должен работать...

abigsam
Сообщения: 11
Откуда: Сумы

Сообщение abigsam » 06 янв 2014, 00:03

N1X писал(а):объявлен и определен массив COMMANDS[6]

Исправил :) В исходниках правильно прописано.
Подозреваю есть какая-то тонкость с этими указателями, я пока с ними не очень дружен :(

Аватара пользователя
N1X
Сообщения: 321
Откуда: Беларусь, Гомель

Сообщение N1X » 06 янв 2014, 11:17

А прототип функции как выглядит?

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 06 янв 2014, 11:48

Возможно из-за const, к примеру, comparestr принимает void*, а вы ему const void* подсовываете.

abigsam
Сообщения: 11
Откуда: Сумы

Сообщение abigsam » 06 янв 2014, 14:39

N1X писал(а):прототип функции

Вот он:

Код: Выделить всё

//--- Функция сравнения двух строк ---
uint8_t comparestr (uint8_t (*Base)[],      //Строка, с которой сравнивают
                     uint8_t (*Compare)[]);   //Строка, которая сравнивается


BSVi писал(а):принимает void*, а вы ему const void*

Не совсем понял, void -- это же "пустой" идентификатор ?

Аватара пользователя
BSVi
Адепт
Сообщения: 3576
Откуда: Киев

Сообщение BSVi » 06 янв 2014, 14:43

void - это любой :) В том числе в void * можно передать и char *. В вашем чае при вызове функции нужно написать comparestr ((uint8_t*)COMMANDS[i], &buffer); чтобы снять константность.

abigsam
Сообщения: 11
Откуда: Сумы

Сообщение abigsam » 06 янв 2014, 16:57

В общем, заработало. В функции comparestr() в качестве аргумента я использовал указатели на массив. После того как я переделал её (функцию) для работы с арифметикой указателей, все встало работать.

Код: Выделить всё

//--- Функция сравнения двух строк ---
uint8_t comparestr (uint8_t *Base,                  //Указатель на строку, с которой сравнивают
                    uint8_t *Compare)               //Указатель на строку, которая сравнивается
{
   uint8_t i     = 0;
   uint8_t error = 0;
   //
   while (*((uint8_t*)Base + i) != NULL)   /* while ((*Base)[i] != NULL) -- так было раньше */
   {
      if (*((uint8_t*)Base + i) != *((uint8_t*)Compare + i) )   /* if ((*Base)[i] != (*Compare)[i]) -- так было раньше*/
      {
         error++;
      }
   }
   return error;   
}

Теперь такой вызов функции работает:

Код: Выделить всё

error = comparestr (COMMANDS[i], buffer);

Прояснение в голове произошло после прочтения вот этого: http://www.c-cpp.ru/books/indeksaciya-s-pomoshchyu-ukazateley.
Хотя я все ещё не до конца понял, что же я делал не так :)

Вернуться в «Микроконтроллеры и ПЛИС»



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 17 гостей