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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Корректная обработка utf8 в *nix 
V
    Опции темы
leneCaress
Дата 9.3.2009, 03:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Добрый вечер.

Только-только начала переползать на C++ в Linux. (Раньше писала на C++ много, но только под win).

Не понятен один вопрос...

Допустим локаль в системе может быть как UTF8, так а что-нибудь однобайтовое (например koi8r).
Каким способом обрабатывать содержимое строк, получаемых из файлов, из stdin и пр.

Под виндой было все просто. было либо массив char, либо wchar_t...
Они были соответственно по 1 или 2 байта...

А как быть под *nix??
Во первых хотелось бы не использовать какие-то библиотеки типа boost (хочу сначала научится без них).
Во вторых - хотелось бы, чтобы программа работала кроме линукса, еще на bsd, а в идеале и в win.
В третьих - хотелось бы хорошей производительности.
В четвертых - удобства ТЕ вполне с удовольствием пользовалась бы чем-то вроде std::string, std::stringw.

У меня закрадывается подозрение, что нужно просто считывать все данные в wchar_t[]...
Но мыслей как это сделать по человечески - нету.

Вообщем - "хочу пример" ©  smile 

P.S. гуглила.   smile 

P.P.S. не уверена, что пишу в нужный раздел   smile 
PM MAIL   Вверх
SABROG
Дата 9.3.2009, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

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



Книга "Standard C++ Iostreams and Locales"



Присоединённый файл ( Кол-во скачиваний: 45 )
Присоединённый файл  Standard_C___Iostreams_and_Locales.pdf 210,40 Kb


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
azesmcar
Дата 9.3.2009, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Для начала почитайте тут, довольно много информации по этому поводу.
http://forum.vingrad.ru/forum/topic-249965.html

Цитата

Во вторых - хотелось бы, чтобы программа работала кроме линукса, еще на bsd, а в идеале и в win.


если используете АПИ или что-то наподобие пишите макросы
Код

#ifndef WIN32
    //*nix
#else
    //windows
#endif


Код

В четвертых - удобства ТЕ вполне с удовольствием пользовалась бы чем-то вроде std::string, std::stringw.


в STL есть классы
std::string для анси и
std::wstring для юникода

почитайте ссылку которую я прислал, если останутся вопросы - пишите здесь, обсудим
PM   Вверх
leneCaress
Дата 9.3.2009, 22:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(SABROG @  9.3.2009,  12:44 Найти цитируемый пост)
Книга "Standard C++ Iostreams and Locales"


спасибо smile
раньше пользовалась printf для форматирования строк. думаю что теперь перейду на потоки.


Цитата(azesmcar @  9.3.2009,  15:31 Найти цитируемый пост)
Для начала почитайте тут, довольно много информации по этому поводу.
http://forum.vingrad.ru/forum/topic-249965.html


спасибо!
в принципе с помощью Вашего lexical_cast, думаю, что решу все без проблем =)


Цитата(azesmcar @  9.3.2009,  15:31 Найти цитируемый пост)
если используете АПИ или что-то наподобие пишите макросы


это я вкурсе =)
хотя меня во времена далекой забытой молодости учили локализовывать весь платформо-зависимый код в отдельные модули, а линковать только с необходимым для данной платформы... всеравно периодически #ifdef проскакиевает =)

Цитата(azesmcar @  9.3.2009,  15:31 Найти цитируемый пост)
почитайте ссылку которую я прислал, если останутся вопросы - пишите здесь, обсудим 


хотелось бы услышать авторитетное мнение...

сейчас задача формулируется примерно так: есть большой(>500Mb) объем текстовых данных, висящих у меня в памяти (строки в однобайтовой кодировке или в utf8, кодировка конткретного файла известна), по определенным критериям я его обрабатываю (здесь я обращаю внимания только на цифры, спецсимволы(скобки, кавычки, \t, \n, пробелы) ТЕ кодировка не важна), потом из этого объема я получаю строки(const char*. они содержат символы национальных алфавитов(для меня важны только русский, английский, но возможно в будующем потребуется еще что-то, а-ля китайский)), (это все уже сделано), и вот эти строки мне нужно обработать...
например, самое простое, взять только первые 5 символов и перевести их в верхний регистр...

и вот тут начались проблемы - для латиницы - все просто, а если русский - я получаю "огрызки" символов...
как перевести в верхний регистр, я тоже не знаю.

я вижу для себя такое решение задачи...
данных слишком много, чтобы все их перекодировать.
поэтому перекодировать нужно только на тот момент, когда происходит обработка...
мне это представляется вот так:
const char* в cp1251/koi8-r/utf8  ->  буфер с wchar_t  ->  const char* в utf8

для std::string с utf-8 -> std::wstring -> std::string с utf-8 можно использовать ваш код.. (кстати, не совсем поняла, он для сколькибайтного wchar_t?)
а для преобразования cp1251/koi8-r  ->  utf8 привлечь iconv...
это нормальный способ (ТЕ не через (__|__) )?

еще хотелось бы что-то вроде итератора по utf8 строкам... в загашниках я нашла нужный код, однако есть ли что-либо такое в стандартных библиотеках?


огромное спасибо за помощь!!!


P.S. не пинайте: большой текстовый файл - не моя придумка, а чтобы его обработать нужно произвольно бегать по строкам. эксперементально - самый быстрый способ - загрузить(думаю потом заменить на мапинг, кстати, стоит ли?) его весь в память и уже в памяти мучать.

P.P.S. под никсами раньше писала только на Java, Python...
в них проблема с кодировками как-то решена и никогда даже не всплывала.
PM MAIL   Вверх
inside_pointer
Дата 10.3.2009, 01:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(leneCaress)

и вот тут начались проблемы - для латиницы - все просто, а если русский - я получаю "огрызки" символов...
как перевести в верхний регистр, я тоже не знаю.


Код

SYNOPSIS
       #include <wctype.h>

       wint_t towupper(wint_t wc);



update:
добавил пример

Это сообщение отредактировал(а) inside_pointer - 10.3.2009, 15:23

Присоединённый файл ( Кол-во скачиваний: 13 )
Присоединённый файл  towupper.tar 10,00 Kb
PM MAIL   Вверх
leneCaress
Дата 10.3.2009, 07:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



о... интересно...

значит я могу перевести любую строку в текущей локали в wchar_t с помощью mbsrtowcs, и обратно - в текущую локаль с помощью wcsrtombs....

здорово...

но получается заморочка: pcre работает с utf8, но не wchar... ну вообщем если дойдет до регэкспов - придется наверное туда-сюда конвертить?


спасибо за наводку
PM MAIL   Вверх
inside_pointer
Дата 10.3.2009, 09:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(leneCaress)

но получается заморочка: pcre работает с utf8


Код

[guest@station ~]$ cd /usr/include
[guest@station include]$ FindWord wchar_t | grep typedef
./curses.h:typedef unsigned short wchar_t1;
./ncurses/curses.h:typedef unsigned short wchar_t1;
./ncurses/ncurses.h:typedef unsigned short wchar_t1;
./ncursesw/curses.h:typedef unsigned short wchar_t1;
./ncursesw/ncurses.h:typedef unsigned short wchar_t1;
./X11/Xlib.h:typedef unsigned long wchar_t;



utf8 ?
PM MAIL   Вверх
azesmcar
Дата 10.3.2009, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата

раньше пользовалась printf для форматирования строк. думаю что теперь перейду на потоки.


не надо думать smile переходите однозначно, printf это не C++, это - C и он небезопасен.
Цитата

сейчас задача формулируется примерно так: есть большой(>500Mb) объем текстовых данных, висящих у меня в памяти (строки в однобайтовой кодировке или в utf8, кодировка конткретного файла известна),


обычно текстовые файлы в начале хранят BOM (Byte-order mark), в присланной мной теме есть ссылки на эту тему. Проверьте ваши файлы - чтобы не читать Byte-order mark как часть текста.

Цитата

например, самое простое, взять только первые 5 символов и перевести их в верхний регистр...


сковертируйте в std::wstring а там уже посмотрите функции стандартной библиотеки для работы с std::wstring.

Цитата

например, самое простое, взять только первые 5 символов и перевести их в верхний регистр...


Код

std::wstring t = L"Привет мир!";
std::transform(t.begin(), t.begin() + 5, t.begin(), towupper);


Добавлено через 1 минуту и 49 секунд
http://unicode.org/faq/utf_bom.html

тут тоже много полезного
PM   Вверх
leneCaress
Дата 10.3.2009, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(azesmcar @  10.3.2009,  11:33 Найти цитируемый пост)
не надо думать smile переходите однозначно, printf это не C++, это - C и он небезопасен.


а по производительности оно как?
если нужно много строк форматировать?
(или сильно зависит от реализации?)


Цитата(azesmcar @  10.3.2009,  11:33 Найти цитируемый пост)
обычно текстовые файлы в начале хранят BOM (Byte-order mark)

знаю такого зверя =)
кстати, с BOM сталкивалась только на файлах пришедших с win.



Огромное спасибо!!!
Осилила задачу =)
PM MAIL   Вверх
azesmcar
Дата 10.3.2009, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата

а по производительности оно как?
если нужно много строк форматировать?
(или сильно зависит от реализации?)


думаю если вас заботит разница в производительности между printf и std::cout то вы не тот язык программирования выбрали smile вам сюда
http://forum.vingrad.ru/forum/ASM-forum.html

smile

PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0523 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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