2012-02-27 4 views
6

Я пытаюсь написать код для сравнения двух строк. В windows я могу использовать strcmp, но я хочу писать для многобайтовой строки символов, чтобы она была совместима со всеми другими платформами Могу ли я использовать memcmp? Если нет, то есть какой-либо другой API, который я могу использовать, или мне нужно написать собственный API.Могу ли я использовать memcmp два сравнения многобайтовых символов?

+3

Это зависит от того, используют ли две строки одну и ту же кодировку. –

ответ

1

Если строки используют одинаковое кодирование, memcmp будет работать нормально. Однако имейте в виду, что широкие символы разных размеров на разных платформах.

Если строки используют разные кодировки, вам понадобится библиотека, такая как ICU, чтобы справиться с ней.

2

Если две строки используют ту же кодировку, вы можете использовать memcmp. Если они используют UTF-8, вы даже можете использовать strcmp, так как 0 не отображается в кодированных строках UTF-8. Другой вариант - преобразовать ваши строки в широкие символы, используя mbstowcs.

+0

У этого будут ложные негативы - две одинаковые строки могут быть закодированы в разные шаблоны байтов. Вам нужно сравнить с помощью утилитарной функции Unicode. – StilesCrisis

+0

@StilesCrisis - Можете ли вы привести пример того, как идентичные строки могут иметь разные кодировки UTF-8? Или, если уж на то пошло, как это может произойти с любым другим кодированием (например, ISO 8859-1)? Я сделал вывод, что строки должны использовать одну и ту же кодировку. –

+0

@Ted Hopp: с UTF-8 вы можете кодировать символ в форме с перекрытием (последовательность, которая декодирует значение, которое должно использовать более короткую последовательность: это предложение из википедии). В этом случае memcmp возвращает неверный ответ, но функция сравнения с поддержкой UTF-8 возвращает правильный ответ ... – Malkocoglu

5

Вы должны быть осторожны. Я не эксперт в кодировках Unicode/multi-byte, но я знаю, что с диакритикой иногда две строки можно считать равными, когда их байты не совсем одинаковы. Рекомендуется использовать предварительно проверенные API, потому что строковые кодировки могут стать довольно грязными.

См. the old new thing on case mapping. Я не могу придумать ссылку для диакритики, но если я это сделаю, я опубликую ее.

+0

Это правильно. В некоторых случаях работает 'memcmp'. Для 100% правильности, особенно если используется Unicode в любой форме, 'memcmp' не будет работать. Даже простые символы типа 'é' могут быть представлены более чем одним способом - либо как' é' (один символ Unicode), либо как '' 'в сочетании с' e' (в двух символах Unicode). Большую часть времени они не смешиваются и не совпадают, поэтому сначала вы можете не видеть никаких проблем, но в конечном итоге это укусит вас. – StilesCrisis

+0

Другим способом, в котором строки могли бы считаться равными, но не байт-равными, является то, что ваше сравнение является случайным инвариантом. В этом случае вам нужно выполнить так называемое фальцовочное свертывание, которое позволяет сопоставить регистр верхнего регистра, нижний регистр, заголовок и инвариантные к регистру символы (которые, как указано выше, могут быть в памяти, представленной как несколько кодовых точек ... или нет). – Bingo

+0

Равен после нормализации не то же самое, что и равное. В этом весь смысл нормализации. ОП спрашивал, равны ли две строки строк, а не эквивалентны ли они. –

 Смежные вопросы

  • Нет связанных вопросов^_^