LINUX.ORG.RU

unicode and C: как это работает?


0

0

Есть файл с контентом (1 строка):  요청 드려도 되나요

Output программы: 
  len  = 27
  data = 요청 드려도 되나요
  pos  = 9


Код ниже. Вопрос: используются обычные однобайтовые символы (хотя контент файла отнюдь не однобайтовый) 
для чтения и работы с юникодной строкой. Вопросы: почему это работает? Какой тогда смысл городить всякие wchar_t*
и различные библиотеки для работы с юникодными строками?
В каких случаях данный код будет работать неверно?
Спасибо.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)
{
    FILE* f = fopen("unicode_test", "r");
    char data[50];
    if (!f)
        perror("file open error");

    fgets(data, sizeof(data), f);
    printf("len  = %d\n", strlen(data));
    printf("data = %s\n", data);
    printf("pos  = %d\n", strchr(data, '드') - data);

    fclose(f);

    return 0;
}


P.S. Локаль 'ru_RU.UTF-8'.
anonymous

набери в консоли:
man 7 utf8

fghj ★★★★★
()

>Вопросы: почему это работает?

потому что нифига не работает...

>len = 27
>data = 요청 드려도 되나요

я насчитал здесь 10 символов. может опера что-то оторвала по пути?

>printf("pos = %d\n", strchr(data, '드') - data);

туда же, '드' - это 4ый символ, а не 10ый.

>Какой тогда смысл городить всякие wchar_t* и различные библиотеки для работы с юникодными строками?

чтобы вывод был:
len = 10
data = 요청 드려도 되나요
pos = 3

generatorglukoff ★★
()

потому что юникод такая чтука, что нельзя быть увереным сколько байт будет представлять тот или иной символ. Например "ć" может быть записан как c с последующей черточкой-модификатором, а может и как один символ. Если у тебя будет куча байт, как ты разберешся какой байт к какому символу относится? а так ты знаешь что wchar_t это один символ и ниипет

lester_dev ★★★★★
()
Ответ на: комментарий от lester_dev

> "c" может быть записан как c с последующей черточкой-модификатором, а может и как один символ.

Вот от _этого_ wchar_t ни разу не помогает.

alexs
()

очень просто - вывод у тебя будет работать - но ф-ции типа strlen и прочие будут тебе выдавать неверный результат, потом так же всякие strcmp и еже с ним.

работать это не будет - эээ с старым gcc и возможно с другим компилером.

ну читай короче маны ;) да и сам подумай - у тебя каждый символ не один байт а два - со всеми вытекающими ;)

alphex_kaanoken ★★★
()
Ответ на: комментарий от alphex_kaanoken

Почему strcmp не будет работать? он же в тупую байты сравнивает.

> у тебя каждый символ не один байт а два - со всеми вытекающими ;)

в utf-8 от 1 до 6 байт на символ вроде всегда было.

Reset ★★★★★
()
Ответ на: комментарий от generatorglukoff

>>printf("pos = %d\n", strchr(data, '드') - data);

>туда же, '드' - это 4ый символ, а не 10ый.

Тут вообще скорее всего будет происходить поиск первого байта символа '드'. По-хорошему надо делать strstr(data, "드"), по позицию, понятное дело, мы так определить не сможем.

В общем, используй glib и не парь мозг ни себе не людям. Там отличный API для работы с utf-8 как с обычным char * без всяких заворачиваний в классы/структуры и прочих извращений.

Reset ★★★★★
()
Ответ на: комментарий от Reset

> Почему strcmp не будет работать? он же в тупую байты сравнивает.
а что будет, если ты не просто сравниваешь строки на равно/неравно, а хочешь лексикографически отсортировать набор строк при помощи qsort и в качестве ф-ии сравнения используешь strcmp ;)

cobold ★★★★★
()
Ответ на: комментарий от Reset

>Почему strcmp не будет работать? он же в тупую байты сравнивает.

как показывает практика - далеко не всегда

>в utf-8 от 1 до 6 байт на символ вроде всегда было.

я про блее распространенный случай. то что от 1 до 6 (разве не до 4?) я в курсе;

ладно - про strcmp - strncmp - вот тут начнется гимор.

alphex_kaanoken ★★★
()
Ответ на: комментарий от alphex_kaanoken

>> Почему strcmp не будет работать? он же в тупую байты сравнивает.

> как показывает практика - далеко не всегда

???

swizard
()
Ответ на: комментарий от Reset

>А с strncmp что такое? n разве не означает число байт? Тоже в тупую n байт сравнит и все :)

strncmp(a,"blabla",6);

а теперь думаем ;) что если b,l,a занимают по два байта ? ;)

alphex_kaanoken ★★★
()
Ответ на: комментарий от alphex_kaanoken

угу, в тупую 6 байт (3 буквы) сравнит и все :)

Reset ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.