12

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;
}
6
  • Use strcmp to compare strings. Commented Oct 28, 2015 at 17:01
  • 2
    In the second case you aren't comparing two string objects. The following would work the same as the first case: cout << (std::string("Banana") < std::string("banana")) << endl; Commented Oct 28, 2015 at 17:02
  • 8
    @ThanePlummer No, this is C++. Commented Oct 28, 2015 at 17:06
  • 2
    @ThanePlummer: strncmp does not work with std::string, unless you do the following: strncmp(stringArray[1].c_str(), stringArray[0].c_str()). Commented Oct 28, 2015 at 17:59
  • 1
    While true, in C++ one should (usually) use std::string and its comparison operator overloads and the compare member function. Commented Oct 28, 2015 at 21:47

3 Answers 3

17

stringArray[n] is an std::string, but "Banana" is a string literal (an array of chars).

When you do "Banana" < "banana", both string literals are implicitly converted to char pointers pointing to the char array. < then compares those memory addresses.

Sign up to request clarification or add additional context in comments.

Comments

8

"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().

3 Comments

You could also use std::string("Banana") < std::string("banana")
@Ben: Creating one temporary std::string is enough. Although I'd probably do it like this, too, for readability's sake.
@NathanOliver: For some definition of "a lot"... :) It's certainly less error-prone than using strcmp and confusing the three different results. (I must confess I'd have to read the function's documentation to find out if -1 means that the first or the second is greater, or if it can be any negative number, etc.)
7
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.