-2

Porting code for arduino nano to 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
    };

The function that is giving problems:

    /**
     * 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++));
melpomene
  • 84,125
  • 8
  • 85
  • 148
francisp
  • 19
  • 2
  • 1
    That code looks a lot like https://github.com/jit06/RflinkToJsonMqtt/blob/a49f82e438b4b6e60eb390737a28739661378e7d/Rflink.cpp#L126-L137. – melpomene Sep 21 '19 at 18:21
  • That is where the code comes from. But https://github.com/jit06/RflinkToJsonMqtt/blob/a49f82e438b4b6e60eb390737a28739661378e7d/Rflink.cpp#L126-L137 is for an arduino nano with ethernet shield. I'm trying to run it on a esp8266. Got most to compile already, but I'm stuck on the strcmp_P in the original code. – francisp Sep 22 '19 at 05:37

1 Answers1

2

strArray is an array of string pointers, terminated by a pointer to a zero-length string (why not a NULL pointer?). An array itself decays into a pointer to its first element. You need to dereference the array pointer to access the individual string pointers so you can pass them to strcmp() until you reach that terminator, eg:

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;
}

Alternatively, just use normal array syntax (which works on array pointers) instead of manual pointer arithmetic syntax:

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;
}

Alternatively, it is possible to eliminate the i and j variables completely:

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

That being said, there is no guarantee that two different "\0" string literals in code will point to the same memory address at runtime. Some compilers do merge duplicate strings, but that is very compiler-specific behavior. You should not rely on that. You need to either use strlen(...) == 0 to detect the terminating zero-length string, or better to use a NULL pointer instead.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    "\0" is different from 0. Adding a nullptr at the end of the char* strArray[] were the better solution, though. – datafiddler Sep 21 '19 at 20:10
  • @datafiddler thanks, I updated my answer. I have never seen anyone terminate an array by "\0" rather than null. – Remy Lebeau Sep 21 '19 at 21:54
  • Wel, the original code for the array was including PROGMEM (https://github.com/jit06/RflinkToJsonMqtt/blob/a49f82e438b4b6e60eb390737a28739661378e7d/Rflink.cpp#L126-L137) PROGMEM instructs the arduino compiler to store the variable in flash, rather then in sram. Platformio does not allow that, that is why I removed it. But that is probably the reason not to use a NULL pointer at te end. – francisp Sep 22 '19 at 06:26
  • @Remy Lebeau: `*strArray != "\0"`might always be true, as it's comparing addresses, and its not sure, "\0" will exist only once. I suggest `(strlen(*strArray) != 0)` – datafiddler Sep 22 '19 at 09:57