В чем разница между strcmp() и strcoll()?

Я попытался понять их обоих, но я не нашел различий, кроме strcoll() этот ссылка говорит, что он

сравнивает две строки с нулевым завершением в соответствии с текущей локалью, как определено в категории LC_COLLATE.

Во вторых мыслях, и я знаю, что задаю еще один вопрос для подробного ответа, что именно этот язык для C и С++?

Ответ 1

strcmp() берет байты строки один за другим и сравнивает их как любые байты.

strcoll() берет байты, преобразует их с помощью языка, затем сравнивает результат. Преобразование переупорядочивает в зависимости от языка. На французском языке акцентированные письма приходят после неосвещенных. Итак é после e. Однако é до f. strcoll() исправляется. strcmp() не так хорошо.

Однако во многих случаях strcmp() достаточно, потому что вам не нужно показывать результат, упорядоченный на используемом языке (локали). Например, если вам просто нужно быстро получить доступ к большому количеству данных, проиндексированных строкой, вы должны использовать карту, проиндексированную этой строкой. Вероятно, бесполезно сортировать те, которые используют strcoll(), который, как правило, очень медленный (по крайней мере, по сравнению с strcmp()).

Подробнее о персонажах вы также можете ознакомиться на веб-сайте Unicode.

В отношении языка, это язык. По умолчанию установлено значение "C" (более или менее, не локали). После выбора местоположения локаль устанавливается соответствующим образом. Вы также можете установить переменную среды LC_LOCALE. На самом деле таких переменных очень много. Но в целом вы используете предопределенные функции, которые автоматически принимают эти переменные в учетную запись и делают правильную вещь для вас. (например, даты/времени форматирования, номера/измерения формата, вычисления верхнего/нижнего регистра и т.д.)

Ответ 2

По какой-то причине во всех локалях юникода, которые я тестировал, в нескольких разных версиях glibc, strcoll() возвращает ноль для любых двух хираганов. Это разбивает sort, uniq и все, что каким-то образом взаимодействует с порядками строк.

$echo -e -n 'い\n ろ\n は\n に\n ほ\n へ\n と\n' | сортировать | Uniq

который просто нарушается без ремонта. Люди из разных уголков мира могут иметь разные идеи о том, следует ли "い" размещать до или после "ろ", но никто из них не будет считать их одинаковыми.

И нет, установка вашего языка на японский не имеет значения:

$LC_ALL = ja_JP.utf8 LANG = ja_JP.utf8 LC_COLLATE = ja_JP.utf8 echo -e -n 'い\n ろ\n は\n に\n ほ\n へ\n と\n' | сортировать | Uniq

В каком-то официальном списке рассылки была дискуссия, но угадайте, что это было в 2002 году, и это никогда не было исправлено, потому что людям все равно: https://www.mail-archive.com/[email protected]/msg02658.html

Эта ошибка произошла с нами в какой-то день, и в итоге наш единственный выход состоял в том, чтобы установить локаль сортировки на "C" и полагаться на хорошие свойства кодировки utf-8. Это ужасный опыт, так как не нужно работать в локали "C" при обработке все-японских данных.

Итак, ради вашего здравого смысла, НЕ используйте напрямую strcoll. Более безопасным вариантом может быть:

int safe_strcoll(const char *a, const char *b)
{
  int ret = strcoll(a, b);
  if (ret != 0) return ret;
  return strcmp(a, b);
}

на всякий случай strcoll() решает вкрутить вас...