LINUX.ORG.RU

UTF-16 file C++

 , ,


0

2

Нашел багу в своей программе, смог свести к такому минимальному семплу:

wifstream in("test_utf16", ios::binary);
in.imbue(locale(in.getloc(), new codecvt_utf16<wchar_t, 0x10ffff>()));
wstringstream wss;
wss << in.rdbuf();
auto ret = wss.str();
Утверждается, что этот код работает (по крайней мере так пишут на стек оверфлоу). Тем не менее, ret = L"", если смотреть в отладчике.
$ file test_utf16
test_utf16: Little-endian UTF-16 Unicode text, with no line terminators
$ cat test_utf16
ÿþ?@825B          // это "привет"
В чем подвох?



Последнее исправление: maked0n (всего исправлений: 1)

ÿþ?@825B // это «привет»

Это не «привет». «привет» - это þÿ?@825B

А так УМВР. Для моего «привет» ret.size() == 8, для твоего 5.

slovazap ★★★★★
()

2018

UTF-16

anonymous
()
Ответ на: комментарий от UVV

А терминал умеет в utf16?

Вообще да, но это не важно. Если я пытаюсь считать просто с помощью

wifstream in(...)
wstring str;
in >> str;
или так же с помощью std::basic_ifstream<char16_t>, то получаю ошибку
underflow invalid byte sequence in file.
Размер результирующей строки тоже 0 всегда, а не как у товарища slovazap. Так что дело тут не в терминале думаю.

2018 UTF-16

Встраиваю свое решение в довольно старый код, так что приходится.

maked0n
() автор топика

запарили уже товарищи, которые свято считают что wchar_t обозначает какое-то (пофиг какое именно) из представлений юникода.

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

которые свято считают что wchar_t обозначает какое-то (пофиг какое именно) из представлений юникода.

Судя по описанию ниже wchar_t таки расчитан представлять codepoint из юникода, не?

http://en.cppreference.com/w/cpp/language/types

wchar_t - type for wide character representation (see wide strings). Required to be large enough to represent any supported character code point (32 bits on systems that support Unicode. A notable exception is Windows, where wchar_t is 16 bits and holds UTF-16 code units) It has the same size, signedness, and alignment as one of the integer types, but is a distinct type.

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

по стандарту языков C и C++

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

По этому я бы охотно почитал, если знаешь номер абзаца (ну и естественно версию стандарта). Искать — себе дороже.

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

Да всё там также:

Type wchar_­t is a distinct type whose values can represent distinct codes for all members of
the largest extended character set specified among the supported locales.
Type wchar_­t shall have the same size, signedness, and alignment requirements as one of the
other integral types, called its underlying type.

Так что если реализация поддерживает хотя бы одну юникодную локаль, то wchar_t его тоже поддерживает. У dzidzitop какая-то не та логика, по которой «не обязан» эквивалентно «не бывает».

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

Спасибо!

can represent distinct codes for all members of
the largest extended character set specified among the supported locales

the largest extended character set

Сейчас (самый) наибольший же Unicode?

KennyMinigun ★★★★★
()
Последнее исправление: KennyMinigun (всего исправлений: 2)
Ответ на: комментарий от KennyMinigun

«supported locales» определяется реализацией, но на десктопах на практике Unicode должен быть. А так может и есть какие-то локали больше чем Unicode, хотя вряд ли.

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

какие-то локали больше чем Unicode, хотя вряд ли.

Вот и я сомнемаюсь. Unicode еще даже не заполнен до конца.

KennyMinigun ★★★★★
()

В этом

Little-endian UTF-16 Unicode text

Используй std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian>

Uter
()
Последнее исправление: Uter (всего исправлений: 1)
Ответ на: комментарий от KennyMinigun

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stddef.h.html


wchar_t
Integer type whose range of values can represent distinct codes for all members of the largest extended character set specified among the supported locales; the null character shall have the code value zero. Each member of the basic character set shall have a code value equal to its value when used as the lone character in an integer character constant if an implementation does not define __STDC_MB_MIGHT_NEQ_WC__.



Это в POSIX. Юникодов никаких нет. А в сишном и плюсовом стандарте выискивать не буду - всё в своё время уже нашёл на этот счёт.

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

Стесняюсь спросить что будет если реализация поддерживает EBCDIC и ASCII одновременно?

1) кодовую таблица
если система поддерживает юникод, то wchar_t должен иметь возможность содержать все значения из данной версии юникода. Таблица соответствия не определена.
Сама кодовая таблица wchar_t не определена тоже
2) способ кодирования
даже сам юникод может быть закодирован разными способами. Но в любом случае способ кодирования wchar_t не определён

Что имеем в результате? Что именно обозначает, например, (wchar_t) 0xc5 - не определено.

Что можно сделать с таким типом? Ничего.

А что означает (char32_t) 0xc5? Что-то вполне конкретное. Вот и вся разница между убогим wchar_t и нормальными типами.

dzidzitop ★★
()
Последнее исправление: dzidzitop (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.