Reputation: 1039
I thought that if I used operators such as ">" and "<" in c++ to compare strings, these would compare them lexicographically, the problem is that this only works sometimes in my computer. For example
if("aa" > "bz") cout<<"Yes";
This will print nothing, and thats what I need, but If I type
if("aa" > "bzaa") cout<<"Yes";
This will print "Yes", why is this happening? Or is there some other way I should use to compare strings lexicographically?
Upvotes: 30
Views: 57827
Reputation: 384454
C++20 operator<=>
(spaceship operator) allows you to get <
, ==
or >
in one go
This is another related feature that is of interest for Googlers:
main.cpp
#include <cassert>
#include <string>
int main() {
std::string aa = "aa", ab = "ab";
assert(((aa <=> aa) == 0));
assert(((aa <=> ab) < 0));
assert(((ab <=> aa) > 0));
}
Compile and run:
g++ -ggdb3 -O0 -std=c++20 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
Note that in this case, you can only compare the output of <=>
, which is a std::strong_ordering
object, with 0
and nothing else. E.g. if you attempt:
((aa <=> aa) == 1)
if fails with a 119 line long error message that we so much love from C++ starting with:
main.cpp: In function ‘int main()’: main.cpp:6:25: error: no match for ‘operator==’ (operand types are ‘std::strong_ordering’ and ‘int’)
6 | assert(((aa <=> aa) == 1));
| ~~~~~~~~~~~ ^~ ~
| | |
| | int
| std::strong_ordering
In file included from /usr/include/c++/13/string:43,
from main.cpp:2:
This is mentioned e.g. at: https://en.cppreference.com/w/cpp/utility/compare/strong_ordering
The behavior of a program that attempts to compare a
strong_ordering
with anything other than the integer literal 0 is undefined.
Related broader question: What is the <=> ("spaceship", three-way comparison) operator in C++?
Tested on Ubuntu 24.04, GCC 13.2.0.
Upvotes: 0
Reputation: 71009
Comparing std::string
-s like that will work. However you are comparing string literals. To do the comparison you want either initialize a std::string with them or use strcmp:
if(std::string("aa") > std::string("bz")) cout<<"Yes";
This is the c++ style solution to that.
Or alternatively:
if(strcmp("aa", "bz") > 0) cout<<"Yes";
EDIT(thanks to Konrad Rudolph's comment): in fact in the first version only one of the operands should be converted explicitly so:
if(std::string("aa") > "bz") cout<<"Yes";
Will again work as expected.
EDIT(thanks to churill's comment): since c++14 you can use string literals:
if("aa"s > "bz") cout<<"Yes";
Upvotes: 40
Reputation: 1549
You can use strcmp()
function which is included in the #include <cstring>
header file. strcmp()
compares the two strings character by character. The process will continue until it reaches NULL
or one of the strings become unequal (characters become unequal).
For example:
#include <iostream>
#include <cstring>
void display(char *lhs, char *rhs, int result)
{
if(result > 0)
std::cout << rhs << " precedes " << lhs << std::endl;
else if (result < 0)
std::cout << lhs << " precedes " << rhs << std::endl;
else
std::cout << lhs << " and " << rhs << " are same" << std::endl;
}
int main()
{
char lhs[] = "aa";
char rhs[] = "bz";
int result;
result = strcmp(lhs,rhs);
display(lhs,rhs,result);
result = strcmp(lhs,lhs);
display(lhs,lhs,result);
return 0;
}
Output:
aa precedes bz
aa and aa are same
Upvotes: 0
Reputation: 55019
You are comparing "primitive" strings, which are of type char const *
.
The following is essentially equivalent to your example:
char const * s1 = "aa";
char const * s2 = "bz";
if ( s1 > s2 ) cout<<"Yes";
This is comparing the pointers (the memory addresses of the strings), not the contents.
@izomorphius has suggested some good solutions.
Upvotes: 7