Russian Qt Forum

Программирование => С/C++ => Тема начата: JamS007 от Июль 14, 2011, 02:57



Название: Кроссплатформенная работа со строками
Отправлено: JamS007 от Июль 14, 2011, 02:57
Привет,
прошуршав весь день в гугле, и так ничего не найдя, обращаюсь на форум, который меня не раз спасал.  Коллеги, выручайте и в этот раз, а то уже сил нет.

Краткое описание ситуации:
Есть клиент-серверное приложение, причем клиенты должны быть под самые разные платформы, в том числе и мобильные. Тут тебе и Windows и Linux и Mac OSX и Android и все-все-все. Они не обязательно должны бить написаны на С++, поэтому желательным является использование распространенных стандартов передачи информации.  Следует также сказать, что клиенты для десктопов будут написаны на Qt.
Сервер должен работать только на posix-совместимых системах, сейчас активно рассматриваются freeBSD и Linux. Также, следует сказать, что ради большей производительности и еще по нескольким причинам на сервере используется только чистый с++ в связке с бустом. Кроме буста никакие библиотеки не желательны.

Проблема:
Нужно передавать текстовые строки между сервером и клиентом в обеих направлениях. Самым оптимальным, на мой взгляд, будет использование utf-8, так как она присутствует (или нет?) на всех популярных платформах и ее можно "перегнать" в utf-16 (тоже сомневаюсь) при необходимости. Но, я настолько запутался с этой кодировкой, что уже просто сил нет.

Подскажите, пожалуйста, ответы на следующие вопросы:
 - Если сервер будет запущен в среде, для которой родной является utf-8, то с каким типом мне стоит работать для написания этого самого сервера, std::string или std::wstring, или может какой-то другой?
 - Как строку std::string или std::wstring передать по сети, так, чтобы на стороне клиента она пришла в виде utf-8.
 - Как прочитать присланную строку и, самое главное, как с ней работать, и какой тип для нее использовать?
 - Присланные от клиентов строки должны интерпретироваться как пути ФС, может это важно, не знаю.

Я в юникоде совсем новичок, и может даже элементарного не понимаю, поэтому простите за возможные глупые ошибки.
Спасибо за внимание.


Название: Re: Кроссплатформенная работа со строками
Отправлено: Fess от Июль 14, 2011, 07:09
utf8 в utf16 перегнать можно (и наоборот) алгоритм достаточно несложный и конвертеры есть, хотя бы такой: http://www.google.de/search?q=ConvertUTF.h (когда-то был на unicode.org)
стандарт не определяет кодировку string & wstring. Даже размер wchar_t на разных платформах может быть разным - 2б на Win 4б на unix.
Скорее всего перед отправкой вам нужно будет самостоятельно конвертировать ваши сообщения в utf8 и наоборот. Еще лучше сведения о кодировке включить в само сообщение.
Если работаете с Qt, то учтите, что QString умеет принимать string & wstring и выдавать строки в unicode. QString всегда во внутреннем представлении хранит данные в utf16


Название: Re: Кроссплатформенная работа со строками
Отправлено: GreatSnake от Июль 14, 2011, 10:52
QString всегда во внутреннем представлении хранит данные в utf16
Неправда:
Цитата: assistant
The QString class provides a Unicode character string.
QString stores a string of 16-bit QChars, where each QChar corresponds one Unicode 4.0 character. (Unicode characters with code values above 65535 are stored using surrogate pairs, i.e., two consecutive QChars.)


Название: Re: Кроссплатформенная работа со строками
Отправлено: JamS007 от Июль 14, 2011, 13:26
Спасибо за ответы. Еще такой вопрос: как мне на стороне сервера работать с присланной строкой? Ясное дело что мне нужно ее декодировать, но во что? Как мне узнать родную для системы кодировку или настроить и ее в utf-8, или если кодировка системы итак utf-8 то даже декодировать ничего не нужно будет?


Название: Re: Кроссплатформенная работа со строками
Отправлено: GreatSnake от Июль 14, 2011, 14:08
Сервер должен принимать/отсылать только юникод.
А вот задача клиента это поддерживать.


Название: Re: Кроссплатформенная работа со строками
Отправлено: LisandreL от Июль 14, 2011, 14:13
QString всегда во внутреннем представлении хранит данные в utf16
Неправда:
Цитата: assistant
The QString class provides a Unicode character string.
QString stores a string of 16-bit QChars, where each QChar corresponds one Unicode 4.0 character. (Unicode characters with code values above 65535 are stored using surrogate pairs, i.e., two consecutive QChars.)
Это и есть utf-16 (http://ru.wikipedia.org/wiki/UTF-16):
Цитировать
символы с кодами 0x10000—0x10FFFF — в виде последовательности двух 16-битных слов. Количество символов, представляемых двумя 16-битными словами равно (220). Для представления символов с кодами 0x10000—0x10FFFF используется матрица перекодировки


Название: Re: Кроссплатформенная работа со строками
Отправлено: JamS007 от Июль 14, 2011, 14:19
GreatSnake, так и будет. Вопрос только в том, как работать с принятыми от клиентов строками? Я все никак не пойму, нужно их перекодировать во что-то или нет?

Эти строки выступают в роли файловых путей


Название: Re: Кроссплатформенная работа со строками
Отправлено: Пантер от Июль 14, 2011, 14:20
Принимаешь аксиому: "От клиента ничего кроме utf-8 прийти не может".


Название: Re: Кроссплатформенная работа со строками
Отправлено: GreatSnake от Июль 14, 2011, 14:41
Это и есть utf-16 (http://ru.wikipedia.org/wiki/UTF-16):
Цитировать
символы с кодами 0x10000—0x10FFFF — в виде последовательности двух 16-битных слов. Количество символов, представляемых двумя 16-битными словами равно (220). Для представления символов с кодами 0x10000—0x10FFFF используется матрица перекодировки
utf-16 (http://ru.wikipedia.org/wiki/UTF-16):
Цитировать
UTF-16 (англ. Unicode Transformation Format) в информатике — один из способов кодирования символов из Unicode в виде последовательности 16-битных слов
Unicode - система кодирования
UTF-16 - способ представления


Название: Re: Кроссплатформенная работа со строками
Отправлено: LisandreL от Июль 14, 2011, 14:47
Так в чём неправда у Fess'а то была?


Название: Re: Кроссплатформенная работа со строками
Отправлено: GreatSnake от Июль 14, 2011, 15:04
Так в чём неправда у Fess'а то была?
В том, что в QString символы хранятся без учёта BOM )


Название: Re: Кроссплатформенная работа со строками
Отправлено: brankovic от Июль 14, 2011, 15:35
Если сервер хочет считать число буков (не байт) в строке, и делать строковые операции на них, то с utf8 могут быть проблемы, потому что в utf8 символ может занимать переменное число байт, в таком случае utf32 может быть более актуален.

Но передавать лучше utf8 по любому, utf8 везде одинаковый. А utf16 может быть LE и BE, да и вообще стандарт кривой, лучше с ним не связываться никогда. Пусть перекодировка в utf8 будет проблемой клиента.

Хранить utf8 нужно в std::string (не надо wstring).

Перекодировать что угодно во что угодно можно через libcurl.


Название: Re: Кроссплатформенная работа со строками
Отправлено: zenden от Июль 14, 2011, 17:30
Веселуха начинается тогда, когда нужно работать с юникодными именами файлов, на юниксе и на винде.

В Qt это решено, а вот в чистом С++ приходится писать велосипеды.


Название: Re: Кроссплатформенная работа со строками
Отправлено: alex312 от Июль 15, 2011, 10:14
 Не пишите велосипеды - используйте ICU (http://site.icu-project.org/) !


Название: Re: Кроссплатформенная работа со строками
Отправлено: JamS007 от Июль 16, 2011, 13:21
alex312 ,

Цитировать
Также, следует сказать, что ради большей производительности и еще по нескольким причинам на сервере используется только чистый с++ в связке с бустом. Кроме буста никакие библиотеки не желательны.

видел я этот ICU, он здоровенный как монстр...


Название: Re: Кроссплатформенная работа со строками
Отправлено: alex312 от Июль 16, 2011, 22:48
видел я этот ICU, он здоровенный как монстр...

времена программ размером 4kB давно прошли  ;)