10 char locale[STRBUFSIZE], curloc[STRBUFSIZE];
11 char left[STRBUFSIZE], right[STRBUFSIZE];
12 char buf[BUFSIZ];
13 int count;
14
15 setlocale(LC_ALL, ""); /* установить локаль */
16 strcpy(curloc, setlocale(LC_ALL, NULL)); /* сохранить ее */
17
18 printf("--> "); fflush(stdout);
19 while (fgets(buf, sizeof buf, stdin) != NULL) {
20 locale[0] = '\0';
21 count = sscanf(buf, "%s %s %s", left, right, locale);
22 if (count < 2)
23 break;
24
25 if (*locale) {
26 setlocale(LC_ALL, locale);
27 strcpy(curloc, locale);
28 }
29
30 printf("%s: strcmp(\"%s\", \"%s\") is %d\n", curloc, left,
31 right, strcmp(left, right));
32 printf("%s: strcoll(\"%s\", \"%s\") is %d\n", curloc, left,
33 right, strcoll(left, right));
34
35 printf("\n--> "); fflush(stdout);
36 }
37
38 exit(0);
39 }
Программа читает входные строки, состоящие из двух сравниваемых слов и необязательной локали, использующейся для сравнения. Если локаль дана, она становится локалью для последующих элементов. Программа начинает с любой локалью, которая установлена в окружении.
Массив curloc
сохраняет текущую локаль для вывода результатов; left
и right
являются левым и правым сравниваемыми словами (строки 10–11). Основную часть программы составляет цикл (строки 19–36), который читает строки и выполняет работу. Строки 20–23 разделяют входную строку, locale
инициализируется пустой строкой, если третья строка не предусмотрена.
Строки 25–28 устанавливают новую локаль, если она приведена. Строки 30–33 выводят результаты сравнения, а строка 35 приглашает для дальнейшего ввода. Вот демонстрация:
$ ch13-compare /* Запуск программы */
--> ABC abc /* Ввести два слова */
С: strcmp("ABC", "abc") is -1 /* Программа началась в локали "С" */
С: strcoll("ABC", "abc") is -1 /* В локали "С" идентичные рез-ты */
--> ABC abc en_US /* Слова те же, локаль "en_US" */
en_US: strcmp("ABC", "abc") is -1 /* strcmp() без изменений */
en_US: strcoll("ABC", "abc") is 2 /* рез-ты strcoll() изменились' */
--> ABC abc en_US.UTF-8 /* Слова те же, локаль "en_US.UTF-8" */
en_US.UTF-8: strcmp("ABC", "abc") is -1
en_US. UTF-8: strcoll("ABC", "abc") is 6
/* Другое значение, все еще положительное */
--> junk JUNK /* Новые слова */
en_US.UTF-8: strcmp("junk", "JUNK") is 1 /* предыдущая локаль */
en_US.UTF-8: strcoll("junk", "JUNK") is -6
Эта программа ясно показывает различие между strcmp()
и strcoll()
. Поскольку strcmp()
работает в соответствии с числовыми значениями символов, она всегда возвращает тот же самый результат, strcoll()
понимает проблемы сортировки, и ее результат меняется в соответствии с локалью. Мы видим, что в обеих локалях en_US
заглавные буквы идут после строчных.