Форум программистов, компьютерный форум CyberForum.ru

Как задать локаль для потока? - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 5.00
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
06.05.2013, 08:29     Как задать локаль для потока? #1
Задача прочитать UTF-8 без BOM из файла в std::wstring. Однобайтные символы читаются, а кириллица нет. Если поставить
C++
1
Fille.imbue("ru_RU.UTF8");
, или
C++
1
std::locale::global(std::locale("ru_RU.UTF8"));
, прога аварийно завершается.
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
06.05.2013, 19:26  [ТС]     Как задать локаль для потока? #21
А где?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Убежденный
Системный программист
 Аватар для Убежденный
14219 / 6234 / 988
Регистрация: 02.05.2013
Сообщений: 10,391
Завершенные тесты: 1
06.05.2013, 19:30     Как задать локаль для потока? #22
Цитата Сообщение от taras atavin Посмотреть сообщение
Задача прочитать UTF-8 без BOM из файла в std::wstring. Однобайтные символы читаются, а кириллица нет.
Прочитайте содержимое файла в буфер, а затем вызовите MultiByteToWideChar с CodePage = CP_UTF8.
Получите строку в UTF-16 Little Endian, которую можно будет передать в wstring.
Тащить для такой мелкой задачи Boost и ICU (особенно ввиду объема последней) - страшный overkill.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
08.05.2013, 09:41  [ТС]     Как задать локаль для потока? #23
Дополнительное условие: приложение должно распространяться только в бинарниках, под другой лицензией и иметь закрытый исходный текст.

Добавлено через 1 минуту
Цитата Сообщение от Убежденный Посмотреть сообщение
Прочитайте содержимое файла в буфер, а затем вызовите MultiByteToWideChar с CodePage = CP_UTF8.
Получите строку в UTF-16 Little Endian, которую можно будет передать в wstring.
Цитата Сообщение от Убежденный Посмотреть сообщение
Прочитайте содержимое файла в буфер, а затем вызовите MultiByteToWideChar с CodePage = CP_UTF8.
1. Какого типа должен быть буфер?
2. Как перед чтением файла определить его размер?
3. Преобразование происходит в самом буфере?

Добавлено через 1 минуту
Дайте пожалуйста пример на эту функцию.
Убежденный
Системный программист
 Аватар для Убежденный
14219 / 6234 / 988
Регистрация: 02.05.2013
Сообщений: 10,391
Завершенные тесты: 1
08.05.2013, 09:47     Как задать локаль для потока? #24
Цитата Сообщение от taras atavin Посмотреть сообщение
1. Какого типа должен быть буфер?
char.

Цитата Сообщение от taras atavin Посмотреть сообщение
2. Как перед чтением файла определить его размер?
GetFileSizeEx.

Цитата Сообщение от taras atavin Посмотреть сообщение
3. Преобразование происходит в самом буфере?
Да.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
08.05.2013, 09:48     Как задать локаль для потока? #25
taras atavin, 1) char же (в терминах майкрософта LPCSTR).
2) http://en.cppreference.com/w/cpp/io/basic_istream/seekg
http://en.cppreference.com/w/cpp/io/basic_istream/tellg
C++
1
2
3
fs.seekg(0, std::ios_base::end);
std::ios::pos_type size = fs.tellg();
fs.seekg(0, std::ios_base::beg);
3) http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
09.05.2013, 14:50  [ТС]     Как задать локаль для потока? #26
А где брать cbMultiByte и cchWideChar и какого размера создавать lpWideCharStr? http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
09.05.2013, 20:05     Как задать локаль для потока? #27
Цитата Сообщение от taras atavin Посмотреть сообщение
где брать cbMultiByte и cchWideChar
Мне вас читать учить? Это размеры входного и выходного буферов. В байтах и wchar_t соответственно. Вот где выделяете память под буферы, там и берите.

Цитата Сообщение от taras atavin Посмотреть сообщение
и какого размера создавать lpWideCharStr
Из параноидального расчёта: 1 wchar_t на каждый байт входной последовательности. Вообще на один кириллический символ уходит по два-три байта UTF-8 или один двухбайтовый символ UTF-16, но лучше обойтись без сюрпризов, потому что на пробелы и всякие точки-скобочки уходит по одному байту UTF-8.
Убежденный
Системный программист
 Аватар для Убежденный
14219 / 6234 / 988
Регистрация: 02.05.2013
Сообщений: 10,391
Завершенные тесты: 1
09.05.2013, 20:33     Как задать локаль для потока? #28
MultiByteToWideChar умеет возвращать необходимый размер буфера, если ее "попросить",
указав в cchWideChar нулевое значение. Только учитывайте, что она, в зависимости от
аргументов, может формировать выходной буфер без завершающего нуля.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
09.05.2013, 21:03  [ТС]     Как задать локаль для потока? #29
Вообще не понял. Куда она будет писать результат преобразования, если память не выделялась? И как она вернёт размер буфера в байтах и в символах?
Убежденный
Системный программист
 Аватар для Убежденный
14219 / 6234 / 988
Регистрация: 02.05.2013
Сообщений: 10,391
Завершенные тесты: 1
09.05.2013, 21:11     Как задать локаль для потока? #30
Если вкратце. Есть буфер, размер которого известен, с текстом в кодировке UTF-8.
Текст нужно перевести в UTF-16.

Шаг 1 - определяем размер выходного буфера.
Для этого вызываем MultiByteToWideChar, указывая ноль в cchWideChar.
В описании этого параметра сказано: "If this value is 0, the function returns the
required buffer size, in characters, including any terminating null character, and makes
no use of the lpWideCharStr buffer". В случае успеха функция вернет необходимый
размер выходного буфера, в символах.

Шаг 2 - выделяем буфер необходимого размера (new/malloc/VirtualAlloc и т.п.).

Шаг 3 - вызываем функцию MultiByteToWideChar повторно, теперь в последних
параметрах указываем адрес и размер выходного буфера.

Особое внимание уделите вот этому фрагменту из описания функции:
cbMultiByte [in]

If this parameter is -1, the function processes the entire input string, including the
terminating null character. Therefore, the resulting Unicode string has a terminating
null character, and the length returned by the function includes this character.

If this parameter is set to a positive integer, the function processes exactly the
specified number of bytes. If the provided size does not include a terminating null
character, the resulting Unicode string is not null-terminated, and the returned
length does not include this character.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.05.2013, 14:08     Как задать локаль для потока?
Еще ссылки по теме:

Можно ли задать десятичный разделитель для потока? C++
Как задать кодировку для заголовка окна? C++
C++ Как задать два условия для цикла

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
10.05.2013, 14:08  [ТС]     Как задать локаль для потока? #31
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
Это размеры входного и выходного буферов. В байтах и wchar_t соответственно.
Со входным поняно. Но как сосчитать символы? И сколько надо выделить памяти на wchar_t-буфер?

Добавлено через 35 минут
Повторно вызвал. Как теперь загнать эту строку в std::wstring? Можно написать
C++
1
Result=wchar_tBuffer;
?
Yandex
Объявления
10.05.2013, 14:08     Как задать локаль для потока?
Ответ Создать тему
Опции темы

Текущее время: 08:41. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru