Вторичная проблема: вы должны инициализировать объект типа mbstate_t
с помощью функции mbsinit
, а не memcpy
.Полностью байтов ноль mbsinit
не гарантируется как начальное состояние сдвига, так и даже любое допустимое состояние сдвига.
Основная проблема с вашим кодом заключается в том, что он анализирует строковый литерал,чье представление определяется во время компиляции на основе фактической кодировки этих символов в исходном файле, их представления в исходном наборе символов компилятора и набора символов выполнения, выбранного компилятором.Вы не можете выбрать LC_CTYPE
произвольно - его нужно сопоставить с данными, чтобы функции преобразования в mb работали, как предполагалось.
C не определяет механизм, позволяющий программе определить языковой стандарт, для которого LC_TYPE
соответствует набору символов выполнения и даже не требует наличия такой локали.Документация вашего компилятора должна описывать сопоставление между исходными символами и исполняющими символами, однако, возможно, с точки зрения локали или хорошо известной кодировки, и она может даже описывать способ указать это.В документации вашего компилятора также может быть описан способ указать кодировку, которую он должен принимать для исходных файлов.
Кроме того, , у вас есть дополнительная потенциальная проблема с Unicode, что может быть несоответствие междучто вы, человек, считаете «персонажем» и символами Юникода, которыми он представлен.Как правило, это касается символов с диакритическими знаками, таких как акценты.Многие из наиболее часто используемых из них имеют односимвольное «составное» представление, но также могут быть представлены в виде последовательности базового символа плюс один или несколько комбинирующих символов.
mbrlen()
вряд лиразличайте базовые и комбинирующие символы, поэтому даже без путаницы в кодировке ваш наблюдаемый результат может быть результатом того, что символы представлены в разложенном виде в исходных файлах или преобразованы в эту форму компилятором.
ВнизуСуть в том, что ваша программа зависит от характеристик среды и реализации, которые не указаны в стандарте, поэтому она может вести себя по-разному в разных реализациях, что, по-видимому, и является наблюдением.Ваше конкретное наблюдение может возникнуть, например, из исходного файла, кодируемого в UTF-8, компилятор предполагает, что он будет закодирован в однобайтовой кодировке, такой как ISO-8859-1, а компилятор использует UTF-8.для его набора символов выполнения.
Ваш подход может работать без изменений, если вы убедитесь, что компилятор интерпретирует исходный файл в соответствии с фактической кодировкой этого файла и использует UTF-8 в качестве набора символов выполнения.В качестве альтернативы, в C11 или позже вы можете гарантировать , что кодирование этой конкретной строки во время выполнения - это UTF-8 с использованием литерала UTF-8, например, так:
char * text = u8"öçşğü";
Это заботитсятолько кодирования на стороне исполнения, однако.Вам все еще нужно сопоставить кодировку исходного файла с фактической кодировкой, ожидаемой компилятором, и вы по-прежнему можете зависеть от различий между предварительно составленными и разложенными символами.