LINUX.ORG.RU

Чем определить кол-во байт необходимое для хранения мультибайтной строки

 


0

2

Чем, в условиях только libc, можно определить кол-во памяти необходимое для хранения строки в мультибайтной кодировке (имея wchar_t-строку).

Перемещено Aceler из linux-org-ru

★★★

А если я оставлю комент в ЛОР, а потом топик перенесут в Development, мне защитают скор?

Ты ошибся разделом.

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

Нет. Теперь можно написать что-нибудь по теме и засчитают.

Aceler ★★★★★
()

wcstombs. Вообще рекомендую посмотреть всё семейство функций для работы с многобайтом и мультибайтом.

Но у него есть фатальный недостаток — он зависит от текущей локали. Если тебе надо для Unicode, то можно сделать свою функцию.

a1batross ★★★★★
()

wcstombs()

наверное, как тут уже написали, но на крайняк можно и самому функцию запилить

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

Но у него есть фатальный недостаток — он зависит от текущей локали. Если тебе надо для Unicode, то можно сделать свою функцию.

Если перевести на русский, что ТС хочет, вполне может оказаться, что хочет он перевести wchar_t * в utf-8 char *, а это от локали не зависит.

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

В wchar_t необязательно может быть юникод(он может быть даже любого размера, от 8 до 32 байт), да и локалью тоже не обязательно может быть UTF-8.

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

В wchar_t необязательно может быть юникод

А что там может быть по вашему? Да даже так: а для чего по вашему придуман wchar_t?

да и локалью тоже не обязательно может быть UTF-8.

Безусловно. Но вы читали на что отвечаете? Вообще-то я написал, что ТС скорее всего мог иметь в виду именно это.

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

А что там может быть по вашему? Да даже так: а для чего по вашему придуман wchar_t?

Там может быть всё что угодно. Хоть клингонский имперский иероглифический скрипт. Стантарт любимой всеми Сишки не определяет ни кодировку, ни размер, ни внутреннее представление? ни кодовую таблицу wchar_t.

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

Там может быть всё что угодно. Хоть клингонский имперский иероглифический скрипт.

Вот именно. Там могут содержаться символы непредставимые в текущей локали. Но при изменении локали там ничего не меняется. Но собственно : а слабо вникнуть о чём был риторический вопрос? Какое дело как там внутри представлено? По теме есть что сказать? А, ну это же dzidzitop...

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

вопрос от vodz:

А что там может быть по вашему?

ответ от dzidzitop:

Там может быть всё что угодно.

Ещё вопросы? Или будет какая-то лекция от «практиков» (слесарей 6 разряда) о том, что только юникод там может быть ибо нефиг?

=====

Я wchar_t избегаю и другим советую. Это говно использовать без сеансов любви с переключением глобальной для всей программы локали невозможно.

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

Стантарт любимой всеми Сишки

У тебя уже развился такой чудовищный комплекс по отношению к C, что тебе впору начинать писать книгу «Как перестать беспокоиться о языке программирования, который ты не используешь и начать жить».

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

Я его использую в виде фундамента из трёх слонов и черепахи, на котором построен C++.

Расскажи лучше как нужно работать с переменными типа wchar_t. Например, мне нужно сделать функцию

wchar_t *to_upper_ua(wchar_t *)

, в которой нужно апперкейснуть строчные буквы украинского алфавита.

Как должен выглядеть правильный и переносимый код этой функции на самом современном C11?

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

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

Лес рук просто.

Насущная задача номер 2: прочитать файл с известной кодировкой (не обязательно системная, но она известна заранее) в строку wchar_t *.

Каким образом это можно сделать переносимо на C11?

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

обычно это как-раз и делается через strlen(str)*sizeof(str[0])

Тещемта sizeof(str[0]) == 1.

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

wcstombs() с NULL в первом параметре вернёт длину в мультибайтной кодировке.

Самое то что нужно, большое спасибо, и всем кто поучаствовал.

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

Расскажи лучше как нужно работать с переменными типа wchar_t. Например, мне нужно сделать функцию

wchar_t *to_upper_ua(wchar_t *)

, в которой нужно апперкейснуть строчные буквы украинского алфавита.

towupper()

А зачем ограничиваться только одним языком?

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

И этот towupper() не решает задачу классификации букв украинского алфавита. Он работает сразу со всем и ни с чем конкретно.

А уж сконвертировать в wchar_t * текст не в кодировке системной локали вообще хрен пойми как. Вероятно - никак.

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

в разных языках результат toupper отличается. Например в турецком i в upper-case это совсем даже не I.

utf-8 это как-то решает?

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

И этот towupper() не решает задачу классификации букв украинского алфавита. Он работает сразу со всем и ни с чем конкретно.

Тогда самостоятельно составлять таблицу соответствия нужных букв по чистому юникоду, как раз UCS-4 прямое его воплощение. utf-8 тут не помощник.

А уж сконвертировать в wchar_t * текст не в кодировке системной локали вообще хрен пойми как. Вероятно - никак.

man 3 iconv

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

UTF-8 определяет кодовую таблицу, в которой каждый кодпойнт имент своё чёткое значение, которое может быть правильно интерпретировано. wchar_t никакую кодовую таблицу не определяет. Поэтому с отдельными значениями wchar_t работать семантически не представляется возможным вообще никак.

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

1) wchar_t != unicode.

2) iconv - рабочий вариант, но к wchar_t от не относится вообще никак. Там даже в API wchar_t отсутствует.

iconv (gnu версия) и костылями с безопасным конвертированием в случае однобайтной системной кодировки и живу.

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

А что там может быть по вашему? Да даже так: а для чего по вашему придуман wchar_t?

другие многобайтные кодировки

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

нужно использовать стороннюю библиотеку для этого

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

UTF-8 определяет кодовую таблицу, в которой каждый кодпойнт имент своё чёткое значение, которое может быть правильно интерпретировано. wchar_t никакую кодовую таблицу не определяет. Поэтому с отдельными значениями wchar_t работать семантически не представляется возможным вообще никак.

Ничего не путаешь, может быть наоборот?

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

wchar_t != unicode

wchar_t это тип из которого кодпойнт извлекается с наименьшими усилиями, раз уж на то пошло.

iconv - рабочий вариант, но к wchar_t от не относится вообще никак. Там даже в API wchar_t отсутствует.

Ну вот же, по русски пишут:

man iconv

Although inbuf and outbuf are typed as char **, this does not mean that the objects they point can be interpreted as C strings or as arrays of characters: the interpretation of character byte sequences is handled internally by the conversion functions.

Если бы в интерфейсе функции был void** то ты сказал бы что к char никак не относится?

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

Unicode - определяет кодовую таблицу.

wchar_t - Integral type whose range of values can represent distinct wide-character codes for all members of the largest character set specified among the locales supported by the compilation environment: the null character has the code value 0 and each member of the Portable Character Set has a code value equal to its value when used as the lone character in an integer character constant.

http://pubs.opengroup.org/onlinepubs/007908775/xsh/stddef.h.html

Где тут юникод? Где определение, что, например ((wchar_t) 100500) означает руну «ветер» в системе письменности туземцев Тасмании? Наоборот, говорится, что нихрена тут не определяется.

Для кажного из кодпойнта в юникоде такое описание есть.

Ну и вот ещё смотри: https://en.wikipedia.org/wiki/Wide_character#Relation_to_UCS_and_Unicode

И посмотри на <wchar.h> и насладись «богатством» возможностей: https://ru.wikipedia.org/wiki/Wchar.h

====

Но некоторые люди из комитета уже допёрли, что это говно полное, поэтому в C11 появились типы char16_t, char32_t. Но, правда, никаких инструментов работы с ними (хотя бы printf, scanf) не подвезли. Зато каждое значение этих типов однозначно интерпретируется согласно кодовой таблице Unicode.

====

iconv сделан нормально. С wchar_t он не работает. Он работает с ***конкретными кодировками*** в бинарном формате (т.е. с последовательностью байт).

=====

Хотя, через две(!) конверсии можно из wchar_t получить char32_t: wchar_t * -> wctomb (1) -> mbrtoc32 (2) -> char32_t *

Это успех!

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

Приведи пример желаемой семантической составляющей у других символьных типов.

Ответственность за содержимое возлагается только на алгоритм твоей программы, как и у всех типов. Данные не с потолка же берутся.

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

(char32_t) 0x0436 - означает «ж».

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

Каким образом можно обрабатывать строки char32_t? Берёшь кодпойнт и с помощью документации для юникод обрабатываешь кодпойнты как тебе нужно.

Каким образом можно обрабатывать строки wchar_t? Я вижу только wprintf & wscanf. А если хочется понимать, содержит ли строка букву «ж», то нужно знать кодировку, а для wchar_t кодировка и кодовая таблица не определены.

Так разница понятна?

=====

Но вроде бы через две конверсии (приводил выше) можно получить из wchar_t нормальный юникод и уже работать с осмысленными кодпойнтами через типы char16_t и char32_t. А чтобы напечатать строку char32_t *, нужно тоже делать две конверсии, чтобы получить wchar_t * и напечатать её через wprintf. Гланды через жопу - всё в лучших традициях C.

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