Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> C и Unicode (utf-8), поддержка юникода в стандартном Си 
:(
    Опции темы
GwinnBleidd
Дата 2.7.2008, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 2.5.2008
Где: Украина, Донецк

Репутация: нет
Всего: нет



Задача: сервер, написанный на С (не С++), работает с однобайтовыми кодировками. Необходимо переписать с поддержкой Unicode (желательно utf-8). Сервер писался, тестировался, использовался под ос Linux.

Вопрос: есть ли какие-нибудь стандартные средства работы с utf-8 в Си (C99)? Платформо-компиляторо специфичные (Linux/Gcc)?

Если таковых не имеется, то насколько верным является допущение о том, что можно работать не заморачиваясь над кодировкой? (из-за отсутствия 0-символов в utf-8 последовательности)? Какие операции из стандартных строковых при этом будут выполняться корректно/некорректно?

Спасибо.
PM MAIL   Вверх
Torsten
Дата 2.7.2008, 20:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 10.6.2008
Где: Pskov

Репутация: 3
Всего: 7



Кодировка utf-8 может содержать в себе 1-байные, 2-хбайтные и 3-хбайтные символы. Так же могут быть такие наборы из 2-х и 3-х байт, которых быть не может впринципе (но никто не мешает их подделать специально). Нулевых символов там быть не должно - но никто не мешает их подделать (неприятелю).
Средств в Си (т.е я понимаю функций для работы с utf-8), кажется нет - но я могу ошибатся. просто о них никогда ничего не слышал.

Это сообщение отредактировал(а) Torsten - 2.7.2008, 20:13
--------------------
We have no begining, we have no end. We are infinite.
PM MAIL   Вверх
bsa
Дата 2.7.2008, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



GwinnBleidd, если ты не делаешь оконное приложение (типа midnight commander), то заморочиться придется, так как strlen будет выдавать не количество символов, а количество байт.
Но скорее всего проблем не будет.
Средства работы есть, например iconv - конвертация из кодировки в кодировку.
PM   Вверх
GwinnBleidd
Дата 3.7.2008, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 2.5.2008
Где: Украина, Донецк

Репутация: нет
Всего: нет



Torsten, валидный utf-8 может содержать до 6 байт/символ, хотя представление Юникода в utf-8 специфицировано только для 4х байт. Если "неприятель" передаст 0-символ в utf-8 последовательности, это не так уж критично - такое сообщение можно отсеять. Более критично определение реального размера utf-8 строки в байтах, чтоб не допустить переполнения буфера.


bsa, iconv.h - полезная штука в некоторых случаях, спасибо smile 

Вчера копался в стандарте с99, нашел описание такой штуки как wchar.h. (и еще кой-какие полезные, но сейчас не вспомню - нет стандарта под рукой). Кто-нибудь использовал возможности wchar.h?



Это сообщение отредактировал(а) GwinnBleidd - 3.7.2008, 15:54
PM MAIL   Вверх
Torsten
Дата 3.7.2008, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 10.6.2008
Где: Pskov

Репутация: 3
Всего: 7



Цитата
 валидный utf-8 может содержать до 6 байт/символ

Это кто тебе такое сказал О_о ?

wchar - это короче тот же самый unsigned short, у тебя будет на 1 символ 2 байта, т.е. там можно держать строку, но предварительно ее нужно сконвретить в utf-16 из utf-8, тогда нормально будет.
--------------------
We have no begining, we have no end. We are infinite.
PM MAIL   Вверх
GwinnBleidd
Дата 3.7.2008, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 2.5.2008
Где: Украина, Донецк

Репутация: нет
Всего: нет



Цитата(Torsten @  3.7.2008,  16:17 Найти цитируемый пост)
Это кто тебе такое сказал О_о ?

на документацию ссылку сейчас не дам, но utf-8 символы были отпределены как последовательности до 6 байт длиной. Какой-то из последующих стандартов (2003 года кажется) ограничил использование utf-8 только для формально определенных в Unicode символов, максимальная длина utf-8 символа с этим стала 4 байта. 
Поэтому возникает вопрос о версии стандарта utf-8, которой придерживаются парсеры/кодировщики utf-8.

Цитата(Torsten @  3.7.2008,  16:17 Найти цитируемый пост)
wchar - это короче тот же самый unsigned short, у тебя будет на 1 символ 2 байта, т.е. там можно держать строку, но предварительно ее нужно сконвретить в utf-16 из utf-8

Проверить возможности wchar.h пока не удалось, но предоставляемые  функции, выглядят довольно "вкусными" smile. Да, и не  unsigned short, а целый тип, достаточный чтоб вместить диапазон, зависит от настроек Environment'a 
PM MAIL   Вверх
Torsten
Дата 3.7.2008, 20:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 10.6.2008
Где: Pskov

Репутация: 3
Всего: 7



Посмотри здесь.
Там в конце таблица преобразования utf16->utf-8, ну и наоборот. Максимум 3-байтные символы.

Цитата
Проверить возможности wchar.h пока не удалось, но предоставляемые  функции, выглядят довольно "вкусными" smile. Да, и не  unsigned short, а целый тип, достаточный чтоб вместить диапазон, зависит от настроек Environment'a 

Ну это я не знаю. Я вообще на С++ пишу, но у меня всегда строки в обычном char (ну т.е. std::string), либо в классах, инкапсулирующих от меня детали кодировки. wchar никогда не пользовался.

Это сообщение отредактировал(а) Torsten - 3.7.2008, 20:05
--------------------
We have no begining, we have no end. We are infinite.
PM MAIL   Вверх
GwinnBleidd
Дата 4.7.2008, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 2.5.2008
Где: Украина, Донецк

Репутация: нет
Всего: нет



Цитата(Torsten @  3.7.2008,  18:04 Найти цитируемый пост)
Посмотри здесь.
Там в конце таблица преобразования utf16->utf-8, ну и наоборот. Максимум 3-байтные символы.


Не спорю, при utf16->utf-8 3 байт/символ максимум. Только utf-16 это не совсем уникод smile
В приведенной по вашей ссылке статье есть ссылка на стандарт rfc2279, где описано преобразование ucs-4->utf-8, с использованием максимум 6-байтных последовательностей для кодирования, если не ошибаюсь это "первая" версия стандарта для utf-8. Потом цепочки ограничили 4 байтами

Добавлено через 1 минуту и 34 секунды
впрочем, даже 4 байтные символы в нашей местности редкость smile , просто следует учитывать их возможное существование
PM MAIL   Вверх
Mayk
Дата 6.7.2008, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



Цитата(bsa @  3.7.2008,  00:08 Найти цитируемый пост)
GwinnBleidd, если ты не делаешь оконное приложение (типа midnight commander), то заморочиться придется, так как strlen будет выдавать не количество символов, а количество байт.

man mblen


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
bsa
Дата 6.7.2008, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(bsa @ 2.7.2008,  20:08)
GwinnBleidd, если ты не делаешь оконное приложение (типа midnight commander), то заморочиться придется, так как strlen будет выдавать не количество символов, а количество байт.

Ой. Я немного ошибся - лишнюю "не" влепил. Нужно читать так:
GwinnBleidd, если ты делаешь оконное приложение (типа midnight commander), то заморочиться придется, так как strlen будет выдавать не количество символов, а количество байт.  smile 
PM   Вверх
Lycifer
Дата 7.7.2008, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 144
Регистрация: 4.11.2007

Репутация: нет
Всего: нет



Unicide - всё решает (если я не ошибаюсь)
тип данных wchar_t тебя не устраивает?
PM MAIL ICQ   Вверх
GwinnBleidd
Дата 7.7.2008, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 2.5.2008
Где: Украина, Донецк

Репутация: нет
Всего: нет



Цитата(bsa @  6.7.2008,  12:03 Найти цитируемый пост)
GwinnBleidd, если ты делаешь оконное приложение (типа midnight commander), то заморочиться придется, так как strlen будет выдавать не количество символов, а количество байт.  smile  

Приложение не оконное smile

Цитата(Lycifer @  7.7.2008,  10:44 Найти цитируемый пост)
тип данных wchar_t тебя не устраивает? 

Для внутреннего хранения и обработки данных устраивает вполне, вот только от клиента данные приходят в utf-8, необходима постоянная конвертация туда-сюда, и здесь возникает вопрос скорости подобных преобразований :(

PM MAIL   Вверх
Lycifer
Дата 7.7.2008, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 144
Регистрация: 4.11.2007

Репутация: нет
Всего: нет



Ты хочеш сказать что в wchar_t нельзя записать UTF-8?
PM MAIL ICQ   Вверх
GwinnBleidd
Дата 7.7.2008, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 2.5.2008
Где: Украина, Донецк

Репутация: нет
Всего: нет



Цитата(Lycifer @  7.7.2008,  13:29 Найти цитируемый пост)
Ты хочеш сказать что в wchar_t нельзя записать UTF-8? 

Не уверен, что запись напрямую будет корректна. 

В Си существует понятие многобайтовых символов и расширенных символов. 
Многобайтовые символы - просто char *string, и это корректно за счет того, что символ \0 не может встречаться в такой последовательности. Сюда относится utf-8. При этом, если есть хоть 1 символ с кодом > 127, обычно выполняется условие ((длина строки + 1) != размер строки в байтах). Чтоб узнать n-ный символ, нужно узнать длину предшествующих (n-1) символов.

Расширенные символы (символьный тип данных wchar_t) занимают фиксированный размер, обычно 2 или 4 байта (зависит от реализации) => каждый символ является одиночным объектом данных. 

А для преобразования между многобайтовыми и расширенными символами используются функции mbstowcs и wcstombs из stdlib.h

Это сообщение отредактировал(а) GwinnBleidd - 7.7.2008, 17:50
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0602 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.