Comparing character arrays and string literals in C++
Asked Answered
G

4

9

I have a character array and I'm trying to figure out if it matches a string literal, for example:

char value[] = "yes";
if(value == "yes") {
   // code block
} else {
   // code block
}

This resulted in the following error: comparison with string literal results in unspecified behavior. I also tried something like:

char value[] = "yes";
if(strcmp(value, "yes")) {
   // code block
} else {
   // code block
}

This didn't yield any compiler errors but it is not behaving as expected.

Geo answered 28/10, 2009 at 19:6 Comment(2)
That's not what "CString" means. CString refers to the Microsoft string class from MFC. If you mean null-terminated arrays of char, then the term is "C string" — two words, with only the language name capitalized.Aesir
@Rob: I corrected the title/question to reflect the fact that he's asking about character arrays and string literals.Material
H
24

std::strcmp returns 0 if strings are equal.

Haemal answered 28/10, 2009 at 19:9 Comment(0)
P
28

Check the documentation for strcmp. Hint: it doesn't return a boolean value.

ETA: == doesn't work in general because cstr1 == cstr2 compares pointers, so that comparison will only be true if cstr1 and cstr2 point to the same memory location, even if they happen to both refer to strings that are lexicographically equal. What you tried (comparing a cstring to a literal, e.g. cstr == "yes") especially won't work, because the standard doesn't require it to. In a reasonable implementation I doubt it would explode, but cstr == "yes" is unlikely to ever succeed, because cstr is unlikely to refer to the address that the string constant "yes" lives in.

Palinode answered 28/10, 2009 at 19:9 Comment(5)
+1: The only one who bothered to explain why the OP's first attempt didn't work! Much more important than explaining something that could be found in 10 seconds by reading the strcmp man page (or googling it), in my book.Recall
Not "unlikely". In the above code, value cannot have the same address as the string literal in any conforming implementation. When the warning mentions unspecified behaviour, I assume it means that it's unspecified whether the same literal used in different places ends up with the same address, or not.Coruscate
@onebyone: really? I thought conforming implementations were permitted to coalesce string literals, so that if you had char* s = "yes";, s == "yes" could then potentially be true.Palinode
Sure, that's the bit that is unspecified - it's up to the implementation whether it's true or false. But in the code in the question, value is an array, not a pointer. So there's no way that its first byte can legally have the same address as the first byte of any literal, or for that matter any other object. That's why when it degrades to a pointer for comparison with "yes", it isn't "unlikely" to be equal, it's never equal.Coruscate
Oh, I see what you mean. Yes, what the OP did can't ever work.Palinode
H
24

std::strcmp returns 0 if strings are equal.

Haemal answered 28/10, 2009 at 19:9 Comment(0)
S
3

strcmp returns a tri-state value to indicate what the relative order of the two strings are. When making a call like strcmp(a, b), the function returns

  • a value < 0 when a < b
  • 0 when a == b
  • a value > 0 when a > b
Sanguinaria answered 28/10, 2009 at 19:16 Comment(0)
C
0

As the question is tagged with , in addition to David Seilers excellent explanation on why strcmp() did not work in your case, I want to point out, that strcmp() does not work on character arrays in general, only on null-terminated character arrays (Source).

In your case, you are assigning a string literal to a character array, which will result in a null-terminated character array automatically, so no problem here. But, if you slice your character array out of e. g. a buffer, it may not be null-terminated. In such cases, it is dangerous to use strcmp() as it will traverse the memory until it finds a null byte ('\0') to form a string.

Another solution to your problem would be (using C++ std::string):

char value[] = "yes";
if (std::string{value} == "yes")) {
    // code block
} else {
    // code block
}

This will also only work for null-terminated character arrays. If your character array is not null-terminated, tell the std::string constructor how long your character array is:

char value[3] = "yes";
if (std::string{value, 3} == "yes")) {
    // code block
} else {
    // code block
}
Concerted answered 2/10, 2020 at 10:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.