strcmp не может преобразовать 'char **' в 'const char *' для аргумента '2' в 'int strcmp (const char *, const char *)' - PullRequest
0 голосов
/ 21 сентября 2019

Портирование кода для arduino nano на esp8266

    // list of fields that must be quoted in JSON convertion
     char RFLINK_FIELD_NAME_CMD[]         = "CMD";
     char RFLINK_FIELD_NAME_BAT[]         = "BAT";
     char RFLINK_FIELD_NAME_SMOKEALERT[]  = "SMOKEALERT";
     char RFLINK_FIELD_NAME_SWITCH[]      = "SWITCH";
     char RFLINK_FIELD_NAME_PIR[]         = "PIR";
     char RFLINK_FIELD_NAME_RFDEBUG[]     = "RFDEBUG";
     char* RFLINK_FIELD_STRING[] = {
      RFLINK_FIELD_NAME_CMD,
      RFLINK_FIELD_NAME_BAT,
      RFLINK_FIELD_NAME_SMOKEALERT,
      RFLINK_FIELD_NAME_SWITCH,
      RFLINK_FIELD_NAME_PIR,
      RFLINK_FIELD_NAME_RFDEBUG,
      "\0" // do not remove this mark the end of the array
    };

Функция, которая вызывает проблемы:

    /**
     * check wether a given string is in a array of strings
     */
    bool RfLinkIsStringInArray(char *buffer, char* strArray[]) {
      int i = 0;
      int j;

      while((strArray + i) != '\0') {

        j = strcmp(buffer, (strArray + i++));
        if((j==0)) return true;
      }

  return false;
}
In function 'bool RfLinkIsStringInArray(char*, char**)':
 error: cannot convert 'char**' to 'const char*' for 
argument '2' to 'int strcmp(const char*, const char*)'
     j = strcmp(buffer, (strArray + i++));

1 Ответ

2 голосов
/ 21 сентября 2019

strArray - это массив строковых указателей, оканчивающихся указателем на строку нулевой длины (почему не указатель NULL?).Сам массив превращается в указатель на свой первый элемент.Вам нужно разыменовать указатель массива, чтобы получить доступ к отдельным строковым указателям, чтобы вы могли передавать их на strcmp(), пока не достигнете этого терминатора, например:

bool RfLinkIsStringInArray(char *buffer, char* strArray[])
{
    int i = 0;
    int j;
    while (*(strArray + i) != "\0") // <- note the *
    {
        j = strcmp(buffer, *(strArray + i++)); // <- note the *
        if (j == 0) return true;
    }
    return false;
}

В качестве альтернативы, просто используйте обычный синтаксис массива (который работает науказатели массива) вместо арифметического синтаксиса ручного указателя:

bool RfLinkIsStringInArray(char *buffer, char* strArray[])
{
    int i = 0;
    int j;
    while (strArray[i] != "\0")
    {
        j = strcmp(buffer, strArray[i++]);
        if (j == 0) return true;
    }
    return false;
}

В качестве альтернативы можно полностью исключить переменные i и j:

bool RfLinkIsStringInArray(char *buffer, char* strArray[])
{
    while (*strArray != "\0")
    {
        if (strcmp(buffer, *strArray++) == 0)
            return true;
    }
    return false;
}

При этом,нет никакой гарантии, что два разных строковых литерала "\0" в коде будут указывать на один и тот же адрес памяти во время выполнения.Некоторые компиляторы объединяют дублирующиеся строки, но это очень специфичное для компилятора поведение.Вы не должны полагаться на это.Вам нужно либо использовать strlen(...) == 0 для обнаружения завершающей строки нулевой длины, либо лучше использовать вместо этого указатель NULL.

...