Сравнение строк лексикографически

Я думал, что если бы я использовал такие операторы, как «>» и «‹» в С++ для сравнения строк, они бы сравнивали их лексикографически, проблема в том, что это работает только иногда на моем компьютере. Например

if("aa" > "bz") cout<<"Yes";

Это ничего не напечатает, и это то, что мне нужно, но если я наберу

if("aa" > "bzaa") cout<<"Yes";

Это напечатает «Да», почему это происходит? Или есть какой-то другой способ, который я должен использовать для лексикографического сравнения строк?


person slugo    schedule 12.01.2013    source источник
comment
Проблема в том, что aa и bz не являются string s. Пришло время сообщить авторам руководств и преподавателям, что элемент между должен называться текстовым литералом, а не строкой. Это избавит новичков от путаницы и головной боли!   -  person Emilio Garavaglia    schedule 13.01.2013


Ответы (3)


Такое сравнение std::string будет работать. Однако вы сравниваете строковые литералы. Чтобы выполнить сравнение, вы хотите либо инициализировать std::string с ними, либо использовать strcmp:

if(std::string("aa") > std::string("bz")) cout<<"Yes";

Это решение в стиле С++.

Или альтернативно:

if(strcmp("aa", "bz") > 0) cout<<"Yes";

РЕДАКТИРОВАТЬ (спасибо за комментарий Конрада Рудольфа): на самом деле в первой версии только один из операндов должен быть явно преобразован так:

if(std::string("aa") > "bz") cout<<"Yes";

Будет снова работать, как ожидалось.

РЕДАКТИРОВАТЬ (благодаря комментарию churill): начиная с С++ 14 вы можете использовать строковые литералы:

if("aa"s > "bz") cout<<"Yes";
person Ivaylo Strandjev    schedule 12.01.2013
comment
Только один операнд должен быть преобразован явно. - person Konrad Rudolph; 12.01.2013
comment
Спасибо, это все, что мне нужно было знать. - person slugo; 12.01.2013
comment
@КонрадРудольф правда. Спасибо вам за это. - person Ivaylo Strandjev; 12.01.2013
comment
Я хотел бы добавить, что, начиная с C++14, вы можете написать его еще короче, используя строковые литералы -> if("aa"s > "bz"). - person churill; 11.08.2020
comment
@churill спасибо за это дополнение, я отразил это в своем ответе. - person Ivaylo Strandjev; 11.08.2020

Вы сравниваете «примитивные» строки типа char const *.

Следующее по существу эквивалентно вашему примеру:

char const * s1 = "aa";
char const * s2 = "bz";
if ( s1 > s2 ) cout<<"Yes";

Это сравнение указателей (адресов памяти строк), а не содержимого.

@izomorphius предложил несколько хороших решений.

person Brent Bradburn    schedule 12.01.2013

Вы можете использовать функцию strcmp(), которая включена в заголовочный файл #include <cstring>. strcmp() сравнивает две строки посимвольно. Процесс будет продолжаться до тех пор, пока не достигнет NULL или пока одна из строк не станет неравной (символы не станут равными). Например:

#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;
}

Выход:

aa precedes bz
aa and aa are same
person Geno C    schedule 24.07.2020