When is a char array not a char array....?

I'm trying to compare two char arrays. They appear to be identical, but the comparison fails and I cannot work out why. I'm using it to parse topics from the pubsubclient MQTT library.

I declare a global char array

char PWMTopic[64];

and later in the program, I assign a string to it. The string comes from an SD card.

  if (!strcmp(tempBuf1, strParam[8]))
    strcpy(PWMTopic, tempBuf2);

I print this to the monitor and it is exactly what I expect it to be, properly terminated, with no surprise leading or trailing characters.

When I subsequently compare it to a predetermined char array, they both print out identically, but strcmp fails.

  if (!strcmp(topic, PWMTopic))
    Serial.println("PWM Topic");

Comparing the two, they print out as shown below, the triangle brackets showing there are no hidden chars, making the two different. They are both the same length as well.
<occ/shed/po> - <occ/shed/po>

However, If I use

  if (!strcmp(topic, "occ/shed/po"))
    Serial.println("PWM Topic");

This succeeds.

I can provide the entire code, but it's spread across 6 files and I thought some bright person may be able to point out my mistake from this summary.
No pressure, but my sanity is on the edge :exploding_head:
Thanks

"succeeds" in what way. Did you, perhaps, think that strcmp() returned 'true' on a match and 'false' on a mismatch? strcmp() returns 0 (false) when there is a match. !strcmp() is true when there is a match.

strcmp() returns -1 for "less than", 0 for "equal" and +1 for "greater than.

Hi John, thanks for the reply.

Success means that strcmp() considers them to be identical and returns a 0, so

  if (!strcmp(topic, "occ/shed/po"))
    Serial.println("PWM Topic");

will print

PWMTopic

when both strings are identical

no need, please provide minimal compileable example where comparison fails

1 Like

Are all your strings properly null terminated? If not, that would be "When a char array is not a string"...

Are you saying that this prints "PWM Topic":

  if (!strcmp(topic, "occ/shed/po"))
    Serial.println("PWM Topic");

But this doesn't:

  strcpy(PWMTopic, "occ/shed/po");
  if (!strcmp(topic, PWMTopic))
    Serial.println("PWM Topic");

It sounds like the contents of your buffer is not exactly what you think. I would display the characters in HEX before the comparison, just to be sure there are no invisible characters.

  for (int i = 0; i < strlen(PWMTopic); i++)
  {
    Serial.print((byte)PWMTopic[i], HEX);
    Serial.print(' ');
  }
  Serial.println();
  if (!strcmp(topic, PWMTopic))
    Serial.println("PWM Topic");

stringProblem.ino (1.0 KB)

This file shows the problem. The test.cfg file consists of a single line of text

PWMTopic:occ/shed/po\n

I'm using a Teensy 4.1 board with a built in SD card, hence the reference to BUILTIN_SDCARD. Change this as required for whatever you use; I'm sure the teensy isn't responsible for the problem.

Thanks again, guys.

do this. make sure

if (tempStr[ptr] == '\n')
{
tempStr[ptr] = '\0';

Are you sure the ending is \n and not \r\n?

Johnwasser has nailed it; The '\n' is being included for some reason in the string. If I change

    while (file.available()) 
    {
      tempStr[ptr] = file.read();
      if (tempStr[ptr] == '\n')
      {
        tempStr[ptr] = '\0';
        parseString();
        ptr = 0;
      }
      else
        ptr++;  
    }

to

    while (file.available()) 
    {
      tempStr[ptr] = file.read();
      if (tempStr[ptr] == '\n')
      {
        tempStr[--ptr] = '\0';
        parseString();
        ptr = 0;
      }
      else
        ptr++;  
    }

All is well. Doesn't quite make sense to me, but I'll take it.

Thanks again guys.

See my reply above

killzone_kid - you're right; if I test on '\r' instead of '\n', then it works.

Sanity preserved for a little while longer, thanks again :+1:

try iscntrl instead C iscntrl() - C Standard Library

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