Вы сделали в значительной степени правильный путь. В документации gcc для strcoll
и wcscoll
приведен пример, подобный этому, как правильный способ использования strcoll
или wcscoll
с qsort
.
/* This is the comparison function used with qsort. */
int
compare_elements (char **p1, char **p2)
{
return strcoll (*p1, *p2);
}
/* This is the entry point---the function to sort
strings using the locale's collating sequence. */
void
sort_strings (char **array, int nstrings)
{
/* Sort temp_array by comparing the strings. */
qsort (array, nstrings,
sizeof (char *), compare_elements);
}
Этот пример на самом деле вызывает предупреждение, от которого вы хотите избавиться, но опять же его можно обойти, изменив char**
на const void*
в аргументах на compare_elements
, а затем явно приведя к const char**
.
Вы правы, заметив, что это небезопасно, но безопасность типов не совсем одна из сильных сторон Си. C не имеет ничего общего с шаблонами или шаблонами, поэтому единственный способ, которым qsort может работать с произвольным типом, состоит в том, чтобы его функция сравнения принимала void*
s. Программист должен убедиться, что функция сравнения не используется в контексте, где ей могут передаваться аргументы, которые не являются ожидаемым типом.
Тем не менее, в вашем коде есть ошибка . Функция сравнения получает не сравниваемые элементы, а указатели на сравниваемые элементы . Так что, если элементы являются строками, это означает указатель на указатель. Поэтому, когда вы пишете
return wcscoll(arg1, arg2);
Вы фактически передаете wscoll
a wchar_t**
, когда он ожидает wchar_t*
. Правильный способ сделать это, подавив предупреждение, будет:
int widecharcomp(const void *arg1, const void *arg2)
{
return wcscoll(*(const w_char_t**)arg1, *(const w_char_t**)arg2);
}
такой же уродливый, как и он.
Edit:
Просто еще раз взглянул на верхнюю часть вашего кода. Ваша ошибка здесь действительно двойная. Вы пытаетесь использовать wcscoll
для сортировки символов. Это функция, предназначенная для сортировки строк (которые в C являются указателями на последовательности символов с нулем в конце). Выше написано, если вы пытаетесь отсортировать строки. Если вы хотите отсортировать символы, то wcscoll
не подходит для использования, но все вышеизложенное в отношении qsort
по-прежнему применимо.