C++ Compare char array with string
Solution 1
Use strcmp()
to compare the contents of strings:
if (strcmp(var1, "dev") == 0) {
}
Explanation: in C, a string is a pointer to a memory location which contains bytes. Comparing a char*
to a char*
using the equality operator won't work as expected, because you are comparing the memory locations of the strings rather than their byte contents. A function such as strcmp()
will iterate through both strings, checking their bytes to see if they are equal. strcmp()
will return 0 if they are equal, and a non-zero value if they differ. For more details, see the manpage.
Solution 2
You're not working with strings. You're working with pointers.
var1
is a char pointer (const char*
). It is not a string. If it is null-terminated, then certain C functions will treat it as a string, but it is fundamentally just a pointer.
So when you compare it to a char array, the array decays to a pointer as well, and the compiler then tries to find an operator == (const char*, const char*)
.
Such an operator does exist. It takes two pointers and returns true
if they point to the same address. So the compiler invokes that, and your code breaks.
IF you want to do string comparisons, you have to tell the compiler that you want to deal with strings, not pointers.
The C way of doing this is to use the strcmp
function:
strcmp(var1, "dev");
This will return zero if the two strings are equal. (It will return a value greater than zero if the left-hand side is lexicographically greater than the right hand side, and a value less than zero otherwise.)
So to compare for equality you need to do one of these:
if (!strcmp(var1, "dev")){...}
if (strcmp(var1, "dev") == 0) {...}
However, C++ has a very useful string
class. If we use that your code becomes a fair bit simpler. Of course we could create strings from both arguments, but we only need to do it with one of them:
std::string var1 = getenv("myEnvVar");
if(var1 == "dev")
{
// do stuff
}
Now the compiler encounters a comparison between string and char pointer. It can handle that, because a char pointer can be implicitly converted to a string, yielding a string/string comparison. And those behave exactly as you'd expect.
Solution 3
In this code you are not comparing string values, you are comparing pointer values. If you want to compare string values you need to use a string comparison function such as strcmp.
if ( 0 == strcmp(var1, "dev")) {
..
}
Solution 4
"dev" is not a string
it is a const char *
like var1
. Thus you are indeed comparing the memory adresses. Being that var1
is a char pointer, *var1
is a single char (the first character of the pointed to character sequence to be precise). You can't compare a char against a char pointer, which is why that did not work.
Being that this is tagged as c++, it would be sensible to use std::string
instead of char pointers, which would make == work as expected. (You would just need to do const std::string var1
instead of const char *var1
.
Solution 5
There is more stable function, also gets rid of string folding.
// Add to C++ source
bool string_equal (const char* arg0, const char* arg1)
{
/*
* This function wraps string comparison with string pointers
* (and also works around 'string folding', as I said).
* Converts pointers to std::string
* for make use of string equality operator (==).
* Parameters use 'const' for prevent possible object corruption.
*/
std::string var0 = (std::string) arg0;
std::string var1 = (std::string) arg1;
if (var0 == var1)
{
return true;
}
else
{
return false;
}
}
And add declaration to header
// Parameters use 'const' for prevent possible object corruption.
bool string_equal (const char* arg0, const char* arg1);
For usage, just place an 'string_equal' call as condition of if (or ternary) statement/block.
if (string_equal (var1, "dev"))
{
// It is equal, do what needed here.
}
else
{
// It is not equal, do what needed here (optional).
}
Source: sinatramultimedia/fl32 codec (it's written by myself)
Related videos on Youtube
![Chris Klepeis](https://i.stack.imgur.com/05Db2.jpg?s=256&g=1)
Comments
-
Chris Klepeis over 3 years
I'm trying to compare a character array against a string like so:
const char *var1 = " "; var1 = getenv("myEnvVar"); if(var1 == "dev") { // do stuff }
This if statement never validates as true... when I output var1 it is "dev", I was thinking maybe it has something to do with a null terminated string, but the strlen of "dev" and var1 are equal... I also thought maybe var1 == "dev" was comparing "dev" against the memory location of var1 instead of the value. *var1 == "dev" results in an error.... tried many things, probably a simple solution for the saavy c++ developer (I havent coded c++ in a looong time).
edit: we've tried
if(strcmp(var1, "dev") == 0)
and
if(strncmp(var1, "dev", 3) == 0)
Thanks
edit: After testing at home I'm just going to suggest my co-worker changes the datatype to a string. I believe he was comparing a char array of a large size against a string. I put together a program that outputs sizeof, strlen, etc to help us work through it. Thanks to everyone for the help.
-
NomeN almost 15 yearstry using a debugger to see whether var1 actually is filled with "dev1". Also, if var1 actually is a C++ style string use the c_str() function to get a c style string that can be compared to your char* using strcmp();
-
tchenLooks like you are using raw C strings and not the C++ String class.
-
-
Martin York almost 15 yearsOhhh. I hate putting the 0 on the left (Personal opinion obviously). I think it is more intuative on the right and since you are testing the result against a function no chance of assignment.
-
Drew Delano almost 15 yearsI call this "Yoda Coding" (backwards is the expression, hmmm?). I'd prefer to use compile options to catch accidental assignments.
-
JaredPar almost 15 years@Fred agree with you i do not. :)
-
paulm almost 10 yearsMax compiler warning level, warnings as errors, yoda not required :)