0

Currently trying to fix code that was left unused for a while.

I have two variables: int8_t foo[size] and const char* const bar.

There is an if that checks if(0 != strcmp((char *)foo, bar))

Currently this is failing even though printf("%s | %s", foo, bar) returns two strings the exact same. I also tried strncmp which is also failing.

From researching online, I understand this is most likely due to terminating null bytes however I don't grasp how I would resolve/get around that.

int8_t foo[size];
const char* const bar;

if(0 != strcmp((char *)foo, bar)){
   fail 
}

Expect results are strcmp returning 0 because both strings are the same when printing.

Actual outcome: returning fail.

Actual data: 5352A565712345657567565785658956581
When running printf("Value of foo and bar: %s and %s", foo, bar), both variables return that data above.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
Shox2711
  • 139
  • 1
  • 12

2 Answers2

0

it is not enough to have :

int8_t foo[] = { 'a', 'b' };

to be able to do

if (strcmp(foo, "ab") == 0)
  puts("equals");
else
  puts("not equal");

because strcmp like a lot of other functions working on char * expect a null character signaling the end of the string.

What appends when strcmp goes after 'b' in foo is an undefined behavior

so

int8_t foo[] = { 'a', 'b', 0 };

is a candidate for strcmp(foo, "ab") thanks to the added null char allowing strcmp to not go out of foo in any cases


Note the same problem occurs if you do printf("%s", foo); in the first case, while a null char is not reach in the memory after the 'b' from foo the function printf will try to write the memory as characters, but this is an undefined behavior

bruno
  • 32,421
  • 7
  • 25
  • 37
  • Great answer, thank you for taking the time to make it quite understandable! Just a quick follow up question, foo, while initialized to int8_t foo[size], is passed into a function x(foo). This function populates the array from sqlite3 statements. How would I append a null terminator to foo after it's been populated with it's values? – Shox2711 Jan 31 '19 at 09:20
  • Disregard the above comment, I appended the arrays with a null terminator 0 and still not working. However when I print foo and bar as hex numbers (%x) they are different. foo = vcd16a40 and bar = vcd169e0 – Shox2711 Jan 31 '19 at 09:30
  • @CianO'Shaughnessy the function _x_ has to put the null byte at the end, or it has for instance to return the number of bytes set to be able to add the null at the right position. However to mix string and array of byte is quite strange ;-) – bruno Jan 31 '19 at 09:30
  • @CianO'Shaughnessy how can you have 'v' in hexa ? `int8_t foo[] = { 'a', 'b', 0 }; printf("%d\n", strcmp(foo, "ab"));` will print 0 – bruno Jan 31 '19 at 09:36
0

I'm unable to recreate this scenario despite getting warnings at compilation time. What is the expected behavior? Do you mean that the comparison is failing, or is the code failing to get into the if block? If both arrays contain the same data, the strcmp() will return 0 and then the if block won't be executed.

I'm just trying to clarify. bruno's answer considering strcmp's behavior is also true.