Learning to use strcmp with two array values, compile error

I'm trying to compare two array values, one originates as a const char*, the other is saved as a String (to make things work in this simple first draft).

I'm trying to see if there is a stored value in the array named onList[] like "Bin 4" for example. I'm storing values in the onList[] temporarily to display a short list of active inputs (which is working). Everything is working, except I need to know if an item is already in the onList[] or not.

My code

const char* arInput[]={"Bin 1", "Bin 2", "Bin 3", "Bin 4", "Bin 5", "Bin 6", "Bin 7", "Bin 8", "Bin 9", "Bin 10", "Bin 11", "Bin 12"};
String onList[12]; // examples: "Bin 2", "Bin 4", etc.

byte check_onList(byte col){ // -------- Function to know if input is in onList or not -----------
    if (strcmp(onList[0], "Bin 4")== 0) { // compile error line
     // if (strcmp(onList[0], arInput[i])== 0) {  // alternate comparison 
      //int strcmp(const char *str1, const char *str2) // example
      return 1;}
    else {
      return 0;
     }

I'm getting the compile error:

cannot convert 'String' to 'const char*' for argument '1' to 'int strcmp(const char*, const char*)'

what is the correct method/syntax?
Greatly appreciated.

String objects and C-strings are almost entirely unrelated. Best to avoid Strings on Arduino, as they cause memory problems and even program crashes.

String (to make things work in this simple first draft)

Except that it can't. Working example:

const char * roomList[] = {"Bath", "Bed", "Beyond", "Closet"};
void setup()
{
  Serial.begin(115200);
  for (int i = 0; i < 4; i++)
  {
    if (strcmp("Bed", roomList[i]) == 0) {
      Serial.print("match at index ");
      Serial.println(i);
    }
  }
}
void loop() {}
1 Like

I understand this is not what you are looking for, but if your const array (in flash) is in sorted order, then you can approach the search as a binary-search, cutting the search time by half (average.)

My old example is just brute-force. I have attached an ESP8266 sketch that takes searches to the next level by building indexing.

Spiff_OUI-13.zip (244.3 KB)

I understand the String onList[12] should be a char to match the source data array, arInput[], but days back when I was roughing this in, I had the char onList[12] and I could not push arInput[i] values directly into it, until I made it a String array. I have corrected it.

char * onList[12];

Well, to actually answer the question that OP asked, try:

    if (strcmp(onList[0].c_str(), "Bin 4")== 0) {

This will provide a pointer to the c-string contained in the String object. That's what strcmp() needs for both arguments.

So, now with strcmp I'm trying to use a function with a value passed, to compare the passed value to an array value. So knowing there is a certain value (Bin 1) in this location: onList[0], I'm testing the below code which gives 0 response regardless of onList[] contents..

char * onList[12];

byte check_onList(char on){ // -------- See if an input listed or not -----------
      Serial.println(on);  // Displays an "i" , not 'Bin 1' as expected, ?
    for (int io = 0; io < 4; io++) {
    if (strcmp(on, onList[io])== 0) {  
      Serial.print("Match at index ");
      Serial.println(io);
     // return 1;}
      // else {
       //  return 0;
      }
     }
    }

button2State = digitalRead(inPin2); //----------- Clear onList Button -------------------
if (button2State == LOW) {
    // clear_onList(); //----- Clear onList Array values -----
     //dispOnList();
      Serial.println(check_onList("Bin 1")); // Returns '0' while onList[0] has 'Bin 1' value
       }

That shouldn't even compile let alone work. The function prototype for strcmp() is:

int strcmp( const char *lhs, const char *rhs );

Both arguments must be of type 'char *' (pointer to char). And, the string pointed to must be null-terminated. Your 'on' variable is not a 'char *'.

Thanks gfvalvo,
Its working!

Please post the working code.

my current test code:

const char* arInput[]={"Bin 1", "Bin 2", "Bin 3", "Bin 4", "Bin 5", "Bin 6", "Bin 7", "Bin 8", "Bin 9", "Bin 10", "Bin 11", "Bin 12"};
char * onList[12]; 

byte check_onList(char * on){//(byte col){ // -------- See if an input listed or not -----------
  //Serial.println(on);
  for (int io = 0; io < 12; io++) {
    if (int(strcmp(on, onList[io])== 0)) {  //if (strcmp("Rm xx", arInput[i])== 0) {
     // Serial.print("Match at index ");
     // Serial.println(io);
      return 1;} // found in onList[]
       else {
        return 0; // not found in onList[]
      }
     }
    }

I'm trying to understand why my
byte check_onList(char * on)
function returns a '0' regardless of input. I think this method/example was returning the index value, maybe not the '0' for actual string match, '-1' no match, etc.

I seriously doubt that code works. It returns 0 on the first non-match without checking the entire array. Try:

byte check_onList(char * on) { //(byte col){
  //Serial.println(on);
  for (int io = 0; io < 12; io++) {
    if (int(strcmp(on, onList[io]) == 0)) { //if (strcmp("Rm xx", arInput[i])== 0) {
      // Serial.print("Match at index ");
      // Serial.println(io);
      return 1;
    }
  }
  return 0;
}

That fixed it!
Thanks gfvalvo

const char* arInput[]={"Bin 1", "Bin 2", "Bin 3", "Bin 4", "Bin 5", "Bin 6", "Bin 7", "Bin 8", "Bin 9", "Bin 10", "Bin 11", "Bin 12"};
char * onList[12];  // holds active inputs that are ON, to be displayed

const int inPin2 = 7;
int button2State = 0;  

byte check_onList(char * on){  // ----- Is Input in onList[] or not? ---
  //Serial.println(on);
     for (int io = 0; io < 12; io++) {
       if (int(strcmp(on, onList[io]) == 0)) { 
      return 1;
      }
    }
    return 0;
  }

button2State = digitalRead(inPin2); //----------- Test Button 2 -------------------
if (button2State == LOW) {
      Serial.println(check_onList(arInput[1]));  // 'Bin 2' value in arInput[1] location
   }

So sending check_onList(char * on) with either a literal "value" or a value from the reference array like arInput[2] now results in a '1' if the value is in the onList[] array, or a '0' if the value is not in the in the onList[] array.

My end goal is temporarily logging and displaying the input status of a Modbus digital input module. Maybe the next version will permanently log each event with date/time.

There is no need to cast the result the call as the function returns a number, it's OK to compare it with 0 directly

       if (strcmp(on, onList[io]) == 0) { 

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.