Normandy
Normandy

Reputation: 37

C++ Comparing Strings Using Relational Operator

Can someone clarify what is actually happening during this comparison.

In a C++ program if I have:

string name1 = "Mary";

and I do:

name1 < "Mary Jane" // true

Why is this true? If C++ compares each character to each character and the first mismatched character is the single double quote mark at the end of name1 = "Mary" versus the space value in "Mary Jane" then by the ASCII value a space value is smaller than a single quote mark...

Upvotes: 0

Views: 1738

Answers (3)

Useless
Useless

Reputation: 67772

string name1 = "Mary";

Let's unpick this, there are several things going on.

The token

"Mary"

taken alone is a string literal which roughly evaluates to the array

const char literal_array[5] = { 'M', 'a', 'r', 'y', 0 };

You can see why it's worth having some syntactic sugar - writing that out for every string would be awful.

Anyway, there are no " characters in there - they're used to tell the compiler to emit that string literal, but they're not part of the string itself.

Then, once we know what the right-hand side of the expression is, we can look at the left:

string name1 = "Mary"

is really

string name1(literal_array);

using the constructor

basic_string<char>::basic_string<char>(const char *)

I'm paraphrasing slightly, but it's item 5 here.


name1 < "Mary Jane"

Now we finally know what the left hand side is, we can look at this expression, which expands to

const char literal_array2[10] = { 'M', 'a', 'r', 'y', ' ', 'J', 'a', 'n', 'e', 0 };
operator< (name1, literal_array2)

which is the 9th overload here (at the time of writing), and which calls compare as

name1.compare(literal_array2)

which is described as doing the following:

4) Compares this string to the null-terminated character sequence beginning at the character pointed to by s, as if by compare(basic_string(s))

which takes us back to the first overload:

1) First, calculates the number of characters to compare, as if by

size_type rlen = std::min(size(), str.size()).

Then compares by calling

Traits::compare(data(), str.data(), rlen).

For standard strings this function performs character-by-character lexicographical comparison.

If the result is zero (the strings are equal so far),

note that this is the case when we've just compared "Mary" with "Mary" so far

then their sizes are compared as follows:

size(data) < size(arg)    => data is less than arg    => result <0

where "result <0" means operator< will return true.

Upvotes: 5

templatetypedef
templatetypedef

Reputation: 372982

Although we write string literals in C++ surrounded by quotes, those quotes aren’t actually a part of the string. That means that the strings that you’re actually comparing here are Mary and Mary Jane, without quotes.

C++ compares strings lexicographically, which means that it goes one character at a time until a mismatch is found or one of the strings ends. If no mismatch is found before one of the strings ends, the shorter string compares smaller, hence the result you’re seeing here.

Upvotes: 0

haccks
haccks

Reputation: 106092

Overloaded < operator do not compare " in the string. "" is used to denote strings so that compiler will parse it as an string. They are not the part of the string.

Upvotes: 0

Related Questions