unicode - конвертация, работа и прочее

Страница 2 из 2 Предыдущий  1, 2

Предыдущая тема Следующая тема Перейти вниз

Re: unicode - конвертация, работа и прочее

Сообщение  diakin в Пн Апр 13, 2009 8:08 am

В Unicode каждой букве присваиватся уникальный номер для всех языков, а в ascii используется только 128 верхних байт (из 256) + указание кодовой страницы - т.е. язык.

Вопрос в том, что невозможно перекодировать из ascii в unicode не указав кодовую страницу.
А freebasic это делает. Только смысла в этом 0. Невозможно голые байты перекодировать в числа, привязанные к языку, не указав этот язык.
Речь не столько об исходниках FB, а об обработке строк. Думал использовать встроенные средства fb для поддержки unicod у себя, но похоже, что не получится.

Я еще не смотрел твою библиотеку, хотел сначала получше понять, что и как с уникодом.

Насчет
>одну букву в юникоде можно кодировать по разному.Ну в смысле число (код) для каждой буквы уникален, просто это число можно записывать по разному.
"Одновременно с этим, коды символов стали рассматриваться не как 16-битные значения, а как абстрактные числа, которые в компьютере могут представляться множеством разных способов
...
Юникод имеет несколько форм представления (англ. Unicode Transformation Format, UTF): UTF-8, UTF-16 (UTF-16BE, UTF-16LE) и UTF-32 (UTF-32BE, UTF-32LE).
...
В Microsoft Windows NT и основанных на ней системах Windows 2000 и Windows XP в основном используется форма UTF-16LE. В UNIX-подобных операционных системах GNU/Linux, BSD и Mac OS X принята форма UTF-8 для файлов и UTF-32 или UTF-8 для обработки символов в оперативной памяти."

(я понимаю, что ты все это читал, просто для памяти пишу и здесь)

>Хотя всё равно жаль, что freebasic использует именно char представление, а не wchar.

Тут я не очень разбираюсь. Есть же wstring? Или ты о другом?
Как я понимаю Wstring используется просто для того, чтобы юзать строковые функции для текста Unicode, так же как и для ascii. Непонятно только если я в wstring загоню текст в utf8, который не ровно 2 байта на символ - len () тоже сработает правильно и покажет число символов в строке?
Что-то я сомневаюсь.

diakin

Сообщения : 37
Дата регистрации : 2009-04-06
Откуда : С-Петербург

Посмотреть профиль http://miraxem.com

Вернуться к началу Перейти вниз

Re: unicode - конвертация, работа и прочее

Сообщение  Eric-S в Пн Апр 13, 2009 2:13 pm

freebasic в первую очередь наследник qbasic. И стандартный тип string взял именно из него. А это значит, что один символ размером 1 байт или 8 бит. что соответствует типу char в языке C.
А это значит, что string это ascii или любая 8-битовая кодировка.
Но при этом string по сути являеться объектом. У него есть дескриптор. Этим он отличаеться от строк в языках C.
Но для совместимости были добавлены ещё два типа.
zstring и wstring.
Они соответственно для ascii и юникода. Но заканчиваються терминальным нулём.

zstring ptr соответствует char*
wstring ptr соответствует wchar*

Например visual basic или даже java использует строки (тип string) с юникодом. Во freebasic такого нет. Я попытался реализовать свою версию типа строк для юникода, но сейчас начал немного разочаровываться, чтобы всё было красиво нужно ещё поработать.

Теперь о представлении юникода в компьютере.
Нужно различать две разных вещи.
1. Хранение в оперативной памяти, соответственно в переменных.
2. хранение на диске, в файлах.

Всякие utf-7, utf-8, utf-16 и utf-32, со всеми их вариациями, это для файлов.
И если для utf-16 и utf-32 есть только два стандарта LE и BE, которые говорят о том какой байт писать раньше старший или младший.
То для utf-8 такой проблемы нет. Тут проблема в другом. Как сформировать октет. Причём алгоритм не очень-то чёткий. Я например со старшими кодами до сих пор не разобрался.
Скачал недавно исходник, но всё руки не дойдут.

Юникод в памяти машины, это уже другая проблема. Этим занимаеться уже сама операционная система.
Конечно можно сказать, что windows юникод представляет как utf-16 le, а linux как utf-32 le.
Но это не совсем так. Как я понял для linux le и be роли не играет. По любому всё слово 32-бит процессором читаеться разом.

На счёт же перекодирования ascii в юникод средствами самого freebasic... То тут простите, за ним такого вообще не замечано.

Есть конечно функции
http://www.freebasic.net/forum/viewtopic.php?t=12979&sid=e056a32b48465afe0eaefc2825efaeb6
Но толи мы не поняли как их юзать, толи они сами по себе глючат.
Вот я и сел писать свою библиотечку для перекодировки. Там именно нужно указывать кодовую страницу.

Для windows можно воспользоваться api функциями. Есть ещё несколько библиотек. Но как я смотрел, у них всех есть куча проблем. Моя библиотечка, не исключение.

Когда freebasic читает ascii файл в юникод, то он ничего не кодирует, а транслирует все коды напрямую, особо не заморачиваясь.
Тоже самое получяеться с записью.
По сему выходят либо кракозябры либо вопросики.
Этот вопрос был оставлен на совесть программеров.

Теперь разъясню на счёт кодирование символов.
По сути юникод, это не только кодировка, но и частично оформление текста.
Есть символы для разных пробелов: простой, непрерывный, скрытый и пр.
Чёрточки тоже разные: простой минус, дефис, тере, мягкий перенос, потенциальный перенос и пр.
Есть предваряющие символы, они указывают какая должна быть буква, жирная, курсивом, ударная, с крышкой или точками.
А некоторые предваряющие символы можно смешивать с буквами.
Для кирилицы это буквы "ё" и "й". Особенно жутко для буквы ё. У неё может быть аж четыре варианта (если я правильно понял).

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

Короче жуть полная.
И пока этот вопрос не будет утрясён окончательно придёться нам ещё помучаться.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: unicode - конвертация, работа и прочее

Сообщение  diakin в Пн Апр 13, 2009 2:14 pm

Пример с функцией WChr
(Returns a wide-character string containing one or more Unicode characters)

---
Print "the character represented by the UNICODE code of &h430 is:"; WChr(&h430)
Print "multiple UNICODE characters:"; WChr(&h430, &h431, &h432)
Print "multiple Acii characters:"; Chr(&he0, &he1, &he2)
print "абв"

---------результат на консоли ------------
the character represented by the UNICODE code of &h430 is:а
multiple UNICODE characters:абв
multiple Acii characters:рст
рст

--------------

ха-ха, то есть консоль поддерживает вывод в уникоде.

diakin

Сообщения : 37
Дата регистрации : 2009-04-06
Откуда : С-Петербург

Посмотреть профиль http://miraxem.com

Вернуться к началу Перейти вниз

Re: unicode - конвертация, работа и прочее

Сообщение  Eric-S в Пн Апр 13, 2009 3:06 pm

Ну да Microsoft это и не скрывает.
только это для windows xp и windows 2000. А вот в windows 98 может и не сработать.

Я уже об этом писал.
Если сохранить прогу
Код:

print "Привет, мир!"
в юникоде и откомпилировать, то всё чудесненько выведеться.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: unicode - конвертация, работа и прочее

Сообщение  diakin в Пн Апр 13, 2009 4:03 pm

Eric-S пишет:freebasic в первую очередь наследник qbasic. И стандартный тип string взял именно из него. А это значит, что один символ размером 1 байт или 8 бит. что соответствует типу char в языке C.
А это значит, что string это ascii или любая 8-битовая кодировка.
Но при этом string по сути являеться объектом. У него есть дескриптор. Этим он отличаеться от строк в языках C.

Но для совместимости были добавлены ещё два типа. zstring и wstring.
Они соответственно для ascii и юникода. Но заканчиваються терминальным нулём.

zstring ptr соответствует char*
wstring ptr соответствует wchar*

Например visual basic или даже java использует строки (тип string) с юникодом.

Ну это ведь они просто называются string, а внутри реализованы каждый по своему.

Как в каком компиляторе сделан объект для строк это по моему не важно.
Все равно внутре у него будет какой-то массив, в котором каждому символу будет отводиться или один байт или два в случае уникода. А какими дескриптрами будет этот массив обвешан для удобства пользования это не важно с точки зрения понимания работы с уникодом. Имхо.

В дескрипторе для типа string вроде хранится адрес и длина буфера для хранения текста.
Кодировка может быть однобайтная или двухбайтная для уникода. Ну и соответственно функции работы со строками должны считывать или по одному или по два байта на символ, и смещать указатель на текущий символ при этом на один или два байта.

Вот тут много чего расписано про организацию строковых переменных. Я глубоко не разбирался.
http://www.oreilly.com/catalog/win32api/chapter/ch06.html


Eric-S пишет:
Во freebasic такого нет. Я попытался реализовать свою версию типа строк для юникода, но сейчас начал немного разочаровываться, чтобы всё было красиво нужно ещё поработать.

То есть ты сделал тип stringW Very Happy , по аналогии с типом string с дескриптором и массивом для хранения текста.

' multibite string
type MString
l as uinteger ' длина строки
p as wstring ptr ' указатель на строку
cp as ubyte ' флаг того что это копия (необходимо освободить память)
end type

ха, но тогда как я понимаю в качестве буфера надо использовать просто массив байт, потому что as wstring не может хранить символы с кодом 0. И написать все свои функции типа len(), left(), mid() итд, где при чтении символа и других операциях с символом обрабатывать два байта, а не один. А для UTF8 еще и смотреть, сколько байтов приходится на данный символ.
Ухх..

Eric-S пишет:
Теперь о представлении юникода в компьютере.
Нужно различать две разных вещи.
1. Хранение в оперативной памяти, соответственно в переменных.
2. хранение на диске, в файлах.

Всякие utf-7, utf-8, utf-16 и utf-32, со всеми их вариациями, это для файлов.
И если для utf-16 и utf-32 есть только два стандарта LE и BE, которые говорят о том какой байт писать раньше старший или младший.

Тут ты помоему не совсем правильно проводишь границу.

"Стандарт [unicode] состоит из двух основных разделов: универсальный набор символов (UCS, Universal Character Set) и семейство кодировок (UTF, Unicode Transformation Format).
Универсальный набор символов задаёт однозначное соответствие символов кодам — элементам кодового пространства, представляющим неотрицательные целые числа.
Семейство кодировок определяет машинное представление последовательности кодов UCS."
С точки зрения уникода, где какие UTF применять это дело удобства. utf-8 применяется для файлов потому что там кодировки младших символов совпадают с ascii и поэтому нет проблем с именами файлов. Типа того.



Eric-S пишет:
На счёт же перекодирования ascii в юникод средствами самого freebasic... То тут простите, за ним такого вообще не замечано.

Есть конечно функции
http://www.freebasic.net/forum/viewtopic.php?t=12979&sid=e056a32b48465afe0eaefc2825efaeb6
Но толи мы не поняли как их юзать, толи они сами по себе глючат.
Вот я и сел писать свою библиотечку для перекодировки. Там именно нужно указывать кодовую страницу.


Ну да! Я не понимаю, как можно перекодировать ascii в уникод без указания кодовой страницы, как это делает FreeBasic!



Eric-S пишет:
Для windows можно воспользоваться api функциями. Есть ещё несколько библиотек. Но как я смотрел, у них всех есть куча проблем. Моя библиотечка, не исключение.

MultiByteToWideChar и WideCharToMultiByte у меня даже заработали и я перекодировал ими в UTF8 .


Eric-S пишет:
Когда freebasic читает ascii файл в юникод, то он ничего не кодирует, а транслирует все коды напрямую, особо не заморачиваясь.

Вот это я не понимаю Что значит - транслирует ?



Eric-S пишет:
Теперь разъясню на счёт кодирование символов.
...
Короче жуть полная.
И пока этот вопрос не будет утрясён окончательно придёться нам ещё помучаться.

Зачем они замутили разные возможности представления символов с диакритическими знаками типа
"Представление символа «Й» (U+0419) в виде базового символа «И» (U+0418) и модифицирующего символа « ~» (U+0306)"
непонятно. Только лишняя головная боль.

diakin

Сообщения : 37
Дата регистрации : 2009-04-06
Откуда : С-Петербург

Посмотреть профиль http://miraxem.com

Вернуться к началу Перейти вниз

Re: unicode - конвертация, работа и прочее

Сообщение  diakin в Пн Апр 13, 2009 5:15 pm

Here is the key to understanding strings: when we write the code:

Dim str As String
str = "help"

we are not defining a Unicode character array per se. We are defining a member of a data type called BSTR, which is short for Basic String. A BSTR is, in fact, a pointer to a null-terminated Unicode character array that is preceeded by a 4-byte length field


Вот ключ к пониманию строковых переменных: когда мы пишем такой код:
Dim str As String
str = "help"

мы не определяем массив символов Unicode сам по себе. Мы определяем переменную типа, который называется BSTR,
сокращение от Basic String. Фактически BSTR есть указатель на оканчивающийся нулевым символом массив
символов Unicode, который предваряется полем длиной 4 байта.


diakin

Сообщения : 37
Дата регистрации : 2009-04-06
Откуда : С-Петербург

Посмотреть профиль http://miraxem.com

Вернуться к началу Перейти вниз

Re: unicode - конвертация, работа и прочее

Сообщение  Eric-S в Пн Апр 13, 2009 5:58 pm

diakin пишет:
А это значит, что string это ascii или любая 8-битовая кодировка.
И то и другое. По своей сути string это массив байтов.
Задумано для хранения ascii, но можно хранить и любую 8-ми битовую кодировку и даже просто какие-нибудь бинарные данные.

diakin пишет:
Ну это ведь они просто называются string, а внутри реализованы каждый по своему.
Конечно называються. В том же самом C++ есть string. Я кстати так и не понял в чём его соль.



diakin пишет:
То есть ты сделал тип stringW :D , по аналогии с типом string с дескриптором и массивом для хранения текста.

Код:

' multibite string
type MString
l as uinteger ' длина строки
p as wstring ptr ' указатель на строку
cp as ubyte ' флаг того что это копия (необходимо освободить память)
end type

ха, но тогда как я понимаю в качестве буфера надо использовать просто массив байт, потому что as wstring не может хранить символы с кодом 0. И написать все свои функции типа len(), left(), mid() итд, где при чтении символа и других операциях с символом обрабатывать два байта, а не один. А для UTF8 еще и смотреть, сколько байтов приходится на данный символ.
Ухх..

Можно и массив, например uinteger. А зачем?
Мне при отладке было удобнее wstring.

А символ 0... Никто не заприщает. Это же всего указатель на память. А в память я могу писать всё что захочу.
Дескриптор для того и был нужен, чтобы не обращать внимание на этот символ. Да и во многом именно из-за него мне пришлось реализовывать свои варианты функций.



diakin пишет:
Тут ты помоему не совсем правильно проводишь границу.

"Стандарт [unicode] состоит из двух основных разделов: универсальный набор символов (UCS, Universal Character Set) и семейство кодировок (UTF, Unicode Transformation Format).
Универсальный набор символов задаёт однозначное соответствие символов кодам — элементам кодового пространства, представляющим неотрицательные целые числа.
Семейство кодировок определяет машинное представление последовательности кодов UCS."
С точки зрения уникода, где какие UTF применять это дело удобства. utf-8 применяется для файлов потому что там кодировки младших символов совпадают с ascii и поэтому нет проблем с именами файлов. Типа того.
Дык я о том же и говорю. wstring к utf не имеет никакого отношения. И win api тоже просят ucs.
Хотя вот в консоль нужно выводить именно utf8. Причём весьма хитро.
Мне это не очень понятно. Я однажды вывел в консоль и ascii и unicode? а вывод перенаправил в файл. Так потом еле прочитал то что там получилось.

Я прориагировал в ответ на твою фразу
diakin пишет:
Тут я не очень разбираюсь. Есть же wstring? Или ты о другом?
Как я понимаю Wstring используется просто для того, чтобы юзать строковые функции для текста Unicode, так же как и для ascii. Непонятно только если я в wstring загоню текст в utf8, который не ровно 2 байта на символ - len () тоже сработает правильно и покажет число символов в строке?
Что-то я сомневаюсь.
utf-8 никак нельзя загнать в wstring, можно только переконвертировать. wchar это именно код символа. И кстати нигде не сказано, что wchar размером 16 бит или 2 байта. Даже наоборот везде подчёркиваеться, что эта характеристика платформозависимая.
для dos её вообще нет, так как он юникод не поддерживает.
для windows это 16 бит, а для linux 32 бит.
Но опять же всё очень относительно.

Кстати, в том числе из-за этого фактора я использовал wstring ptr а не uinteger ptr.

А если под windows писать wchar больше 65536, то это не вызовет ошибки. Просто код будет урезан.




diakin пишет:
Вот это я не понимаю Что значит - транслирует ?
Да в смысле просто передаёт, ничего не кодируя.
Для ascii это нормально.
А вот кирилицу cp1251 или cp866 конечно же ломает.

При кодировании в юникод из 8-битовой кодировки.
Берётся таблица соответствий, находиться символ для кодовой страницы, а пишеться соответствующий юникод.
А при трансляции, берёться код и пишеться.
если lдля символов 61 и 62это безболезненно, то для 161 и 162 получается "?" при отображении.
ЕЕсли я не ошибаюсь в юникоде просто нет символов в диапазоне от 129 до 256. А именно туда и попадает кирилица при трансляции.


diakin пишет:
Зачем они замутили разные возможности представления символов с диакритическими знаками типа
"Представление символа «Й» (U+0419) в виде базового символа «И» (U+0418) и модифицирующего символа « ~» (U+0306)"
непонятно. Только лишняя головная боль.
Нет, идея-то сама не плохая. А делалось это с ориентировкой на другие языки, где диакритические символы играют более важную роль.

В прочем у нас... Я как-то ковырял MySql? и там нашел несколько очень интересных функций. Например можно сделать поиск по тексту без учёта буквы "е" или "ё". Это очень удобная примочка. И сделана она была не без помощи юникода.
Да и вообще такая информация бывает не лишней.
А вот сделано всё действительно коряво. И по хорошему, нужно всю спецификацию перетрясти и пересмотреть забив на обратную совместимость.
Да и ещё в предачу опубликовать исходники всех нужных функций.

Я же ведь юникодом заинтересовался не из-за мультиязычности приложений. А именно из-за возможностей обработки естественного языка.
И вот тут-то и видны преимущества более чёткого разделения символов. А также их сопровождение. Есть языки где смысл символа изменяеться от того, как он написан жирно или нет. Да и символ ударения тоже нужен.
Хотя при классических операциях поиска или конвертации дополнительные символы будут просто мешать. По этому нужно тонко понимать что и как делаеться.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: unicode - конвертация, работа и прочее

Сообщение  Eric-S в Пн Апр 13, 2009 6:02 pm

diakin пишет:Here is the key to understanding strings: when we write the code:

Dim str As String
str = "help"

we are not defining a Unicode character array per se. We are defining a member of a data type called BSTR, which is short for Basic String. A BSTR is, in fact, a pointer to a null-terminated Unicode character array that is preceeded by a 4-byte length field


Вот ключ к пониманию строковых переменных: когда мы пишем такой код:
Dim str As String
str = "help"

мы не определяем массив символов Unicode сам по себе. Мы определяем переменную типа, который называется BSTR,
сокращение от Basic String. Фактически BSTR есть указатель на оканчивающийся нулевым символом массив
символов Unicode, который предваряется полем длиной 4 байта.


Это верно для visual basic и не верно для freebasic, см выше, где я упоминал qbasic.

Где-то здесь на форуме уже поднималась тема, как string преобразовать в bstr, чтобы подключить к vb6 библиотеку сделанную на freebasic.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: unicode - конвертация, работа и прочее

Сообщение  diakin в Пн Апр 13, 2009 11:20 pm

>А при трансляции, берёться код и пишеться.

То есть что, берется ascii код букв а б в hex E0 E1 E2, добавляет спереди нули 00E0 00E1 00E2
и считает, что он перекодировал в unicode??? Ну то есть да, для нижней части таблицы это верно.
OMG...

>Если я не ошибаюсь в юникоде просто нет символов в диапазоне от 129 до 256. А именно туда и >попадает кирилица при трансляции

Нет 00E0 00E1 00E2 соответствуют символы
U+00E0 à c3 a0 LATIN SMALL LETTER A WITH GRAVE
U+00E1 á c3 a1 LATIN SMALL LETTER A WITH ACUTE
U+00E2 â c3 a2 LATIN SMALL LETTER A WITH CIRCUMFLEX

diakin

Сообщения : 37
Дата регистрации : 2009-04-06
Откуда : С-Петербург

Посмотреть профиль http://miraxem.com

Вернуться к началу Перейти вниз

Re: unicode - конвертация, работа и прочее

Сообщение  Eric-S в Вт Апр 14, 2009 7:03 am

Я не очень-то вникал в суть операции. Но перекодировки однозначно не происходит.
точно также ведут себя и функции wstr() и asc(). Они только передают числа. И я не замечал, чтобы расширенные символы сохранялись.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: unicode - конвертация, работа и прочее

Сообщение  Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Страница 2 из 2 Предыдущий  1, 2

Предыдущая тема Следующая тема Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения