Reputation: 319
The following code prints
1
0
And I've been wondering why the values are different if the comparisons are using the same string… I've been struggling with this for a while and cannot figure out why they return different boolean values.
int main()
{
string stringArray[] = { "banana","Banana","zebra","apple","Apple","Zebra","cayote" };
cout << (stringArray[1] < stringArray[0]) << endl;
cout << ("Banana" < "banana") << endl;
return 0;
}
Upvotes: 12
Views: 1260
Reputation: 180500
"Banana" < "banana"
is not comparing the contents of the strings. It is comparing the pointers that "Banana"
and "banana"
resolve to.
To compare cstyle strings without converting them to a std::string
you can use strcmp()
.
Upvotes: 8
Reputation: 27528
string stringArray[] = { "banana","Banana","zebra","apple","Apple","Zebra","cayote" };
This means that you get a bunch of std::string
objects, created from char const*
s resulting from the individual string literals.
Consider a single std::string
initialisation:
std::string s = "...";
The literal on the right is of type char const[4]
. It "decays" to a char const*
used by std::string
's constructor.
The same happens when you initialize an array of std::string
objects from string literals.
cout << (stringArray[1] < stringArray[0]) << endl;
For std::string
, using the <
operator means lexicographical comparison. Therefore, this uses lexicographical comparison and has the expected result.
cout << ("Banana" < "banana") << endl;
In this case, there is no std::string
involved. You compare two char const[7]
with each other.
What does this mean? A completely different thing, as it turns out. Both arrays "decay" to a char const*
to their first element. The result of comparing two unrelated pointers with <
is unspecified. You are lucky to receive 0 as a result, because you may as well receive 1 and not notice the error. Compilers can also generate a warning for this, for example:
warning: comparison with string literal results in unspecified behaviour
So, as you can see, this operation has absolutely nothing to do with lexicographical comparison.
One way to solve this problem is to turn at least one of the operands into an std::string
:
cout << (string("Banana") < "banana") << endl;
A <
comparison between an std::string
and a char const*
(or vice versa) is defined to be lexicographical.
Upvotes: 7
Reputation: 42828
stringArray[n]
is an std::string
, but "Banana"
is a string literal (an array of char
s).
When you do "Banana" < "banana"
, both string literals are implicitly converted to char
pointers pointing to the char
array. <
then compares those memory addresses.
Upvotes: 17