Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.22.119.251] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Из того, что нагуглилось по Unicode, это просто стандарт кодирования символов (сильно в вопрос не погружался).
Есть проекты в Visual Studio 2019 (MFC-шные) В настройках проекта есть настройка набора символов: типа ничего, юникод и многобайтовая. Есть приложение. 1) Считывает данные по сети SNMP в char[] 2) Считывает данные ОС NetAPI (тоже сетевую информацию) в WCHAR[] (режим FORCE_UNICODE) 3) Работает с MySQL через std::string 4) и для отладки вспомогательное GUI (приложение работает как служба) работает со CString В приложении используется std::wstring 1) конвертируется string->wstring 3) для работы с базой (API) используется string, при работе конвертируем string<->wstring using CStr = std::string; using CWideStr = std::wstring; // convert UTF-8 string to wstring CWideStr utf8_to_wstring(const CStr &str) { std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv; return myconv.from_bytes(str); } // convert wstring to UTF-8 string CStr wstring_to_utf8(const CWideStr &str) { std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv; return myconv.to_bytes(str); } Смотрю на весь код, и как-то ощущается, что wstring то мне и не нужен. Если в настройках проекта отключить юникод, то для CString будет использоваться char, т.е., как я понимаю, для MFC классов поменяется char/wchar_t. Так вот, без выключений этой опции (оставить юникод), могу спокойно отказаться от wstring, конвертировать только для отображения информации (но без юникода и конвертировать не придется), ну и NetAPI тогда конвертировать в string (что и так происходит при записи в субд). Но как-то глобально скажется, отключение юникода в настройках проекта? Может там другие библиотеки будут использоваться, у которых нет поддержки юникода или что-то еще... (используются языки английский, русский и казахский) + В другом приложении работаю с MS SQL, который, как я понимаю, работает с WCHAR #include <sqlext.h> #include <sqltypes.h> #include <sql.h> |
Сообщ.
#2
,
|
|
|
А зачем отказываться от Unicode? Тем более если нужны 3 разных языка (не знаю - казахский алфавит влезает в старшую половину 128...255?)
Можно конечно поставить в настройке набора символов: NONE и везде будут использоваться char-варианты библиотечных функций. А при необходимости Unicode: явно использовать wchar_t и варианты функций с явным указанием Unicode-библиотеки - типа SendMessageW(). Но вот у меня сейчас есть большой проект, где изначально я так и сделал (все строки - char), а теперь хотелось бы переделать под Unicode (потребовались разные языки), но уже перелопатить весь проект - это нужно подвиг совершить, слишком трудозатратно. |
Сообщ.
#3
,
|
|
|
По размеру должен, алфавит 42...
Но у меня есть VBScript, с русскими и казахским текстом, при файле UTF-8 не работает, заработало только при UTF-16. Так что.... Вопрос в том, как и на что влияет эта настройка. |
Сообщ.
#4
,
|
|
|
Цитата Black_Dragon @ Вопрос в том, как и на что влияет эта настройка. В первую очередь повлияет на используемую библиотеку функций. При "NONE" на место SendMessage() будет подставлена SendMessageA(), а при "UNICODE" - SendMessageW(). Но также можно и явно указывать требуемый вариант функции. Если нужно. Например - в моём приложении скомпилённом в "NONE", есть пара мест где я устанавливаю Unicode-надписи для контролов через SendMessageW(). Всё работает ок. |
Сообщ.
#5
,
|
|
|
Цитата jcxz @ В первую очередь повлияет на используемую библиотеку функций. При "NONE" на место SendMessage() будет подставлена SendMessageA(), а при "UNICODE" - SendMessageW(). Это просто выбор макроса в инклудах для удобства, я про них знаю... Есть ли какие-то существенные изменения в тех же либах или где-то еще (подводные камни), или это только для удобство? |
Сообщ.
#6
,
|
|
|
Цитата Black_Dragon @ Но как-то глобально скажется, отключение юникода в настройках проекта? Может там другие библиотеки будут использоваться, у которых нет поддержки юникода или что-то еще... (используются языки английский, русский и казахский) Будут вызываться функции принимающие юникод строки(с префиксом W) - если включен юникод, и будут вызываться функции принимающие ASCII строку, если ты выключишь юникод, допустим, в коде вызывается у тебя там функция: GetComputerName Если включен Unicode, то вызовется эта версия: https://docs.microsoft.com/ru-ru/windows/wi...etcomputernamew Если включен ansi, то вызовется эта версия: https://docs.microsoft.com/ru-ru/windows/wi...etcomputernamea Разница в принимающих аргументах. Так же всякие классы обертки типа CString будут использовать CHAR вместо WCHAR(для юникодной конфигурации). Если ты везде юзал MFCШные универсальные типы, аля там TCHAR, LPCTSTR, CString и т.д., вместо например char, std::string/std::wstring, то проблем быть не должно, при смене настройки, просто будут типы данных ansi использоваться, размер типа станет 8 бит(для юникода 16 бит). Ну и не будут отображаться русские/казахские/еще какие то символы, хотя через локаль настроить можно. Ну и если вдруг что то случится, скорее всего будет ошибка компиляции, т.к. типа данных изменится, и если ты где то передавал явную юникод строку в функцию например GetComputerName(или подобной), то после смены текущей настройки будет вызвана функция с префиксом А, которая требует ascii строку, а не wchar_t, соответственно сразу увидишь эти места. |
Сообщ.
#7
,
|
|
|
Сообщ.
#8
,
|
|
|
Скрытый текст ЫукпШ, злой ты человек! Я понимаю бы - Рихреру в карман. Так ты поощряешь этих кривых калдырей-плагиаторов. Будь мужиком - начни давать ссылки на электронные версии полезного оригинального материала! Это шутка, есличо! |
Сообщ.
#9
,
|
|
|
Цитата Wound @ (с префиксом W) Про это я знаю. Это макросы для удобства. В программе текст храниться в std::wstring. Данные с сети считываются: 1) std::string (конвертация в std::wstring) 2) std::wstring Данные считываются и записываются в СУБД MySQL (UTF-8) 3) std::string (конвертация в std::wstring и обратно) Ну и для версии программы с GUI 4) CString для вывода в таблицу и т.п. Если опустить п.4, то кажется оптимальнее использовать std::string, а если вообще отключить уникод, то CString будет char, будут ли проблемы с выводом unicode... Так же при работе с MS SQL можно так же char/wchar юзать, uncode (utf-8) будет работать в случае char? Вообщем цель, сидеть на 8-битах с русским/казахским текстом возможна ли? |
Сообщ.
#10
,
|
|
|
Цитата Black_Dragon @ Вообщем цель, сидеть на 8-битах с русским/казахским текстом возможна ли? Наверное, не пробовал. Попробуй добавить второй язык в систему и написать hellow world в котором в консоль вывести казахский текст, только перед этим выстави казахскую локаль. |
Сообщ.
#11
,
|
|
|
Если сидеть на 8 битах, то неизбежно возникает необходимость явно задавать кодовую страницу. Что немножечко неудобно, в свете современных тенденций разработки. Тот же UTF-8 позволяет сформировать строку из русских букв, казахских, туда же пришить немецкие умляуты и китайские иероглифы. В одной и той же строке.
Возможно, это из-за недопонимания, что UTF-8 - это не строка в привычном понимании языков программирования, а скорее байтовый формат буфера? И если мы вводим понятие у себя кодовой страницы для восьмибитной строки, то по сути переизобретаем UTF-8 из желудей и спичек. |
Сообщ.
#12
,
|
|
|
Цитата Mr.Delphist @ Тот же UTF-8 позволяет сформировать строку из русских букв, казахских, туда же пришить немецкие умляуты и китайские иероглифы. В одной и той же строке. Насколько я понимаю, сделано так: UTF-8 - это одна из нескольких кодировок Юникода. Широко используется в Linux/Unix системах, в том числе для вывода в консоль. У Виндуса используется Юникод - кодировка в формате UTF-16. Но для совместимости со старыми приложениями DOS в консоли используется кодировка OEM. Т.е.старая, байтовая, со всеми её недостатками. Виндус своими встроенными средствами может делать любые преобразования ASCII-UTF8-UTF16-OEM. Так что с преобразованиями проблем не будет, но приложение лучше делать Unicode (UTF-16). Это повышает быстродействие, потому что любая ASCII - функция системы использует дополнительное преобразование ASCII<->Unicode и последующий вызов Unicode - функции. --- Иллюзия думать, что "сейчас я запишу в Unicode-строку" русские, арабские и японские символы и увижу всё это на экране. Скорее всего, на экране будут кракозябры. Поскольку Unicode - это необходимое условие, но не достаточное. Нужно чтобы используемый фонт имел в своём составе отображение всех этих символов. Но разработчик фонта не знает заранее, какие символы мне понадобятся. Значит, надо производить поддержку всех символов, изобретённых Человечеством, а это действительно технически сложно. --- Разговор про казахский язык вообще не понятен. Отображаются не языки, отображаются алфавиты. До некоторого времени, Казахстан использовал кириллицу. Не так давно, руководство Казахстана объявило, что переходит на латиницу. В любом случае, используемые символы алфавитов предназначены для воспроизведения слов на казахском языке - но своего казахского алфавита ведь нет ?. Если это так, можно предположить, что русская OEM (CP-866) - кодировка подходит для казахского языка. Та самая, что у русского Виндуса установлена для консоли по умолчанию. |
Сообщ.
#13
,
|
|
|
ЫукпШ, чуть малеха ошибаешься. Все дело в терминологии ... Просто нужно еще раз обратиться к английской аббревиатуре используемых терминов.
UNICODE - представляет собой стандарт кодирования символов, и определяет набор символов, а если точнее - глифов (т.е. символов с их начертанием и принадлежности языковой плоскости). Последняя версия юникода 13.0 (март 2020) определяет 143 859 символов, что эквивалентно ) hex - 0002 31F3 UTF (UTF-8,UTF-16,UTF-32) - В вики написана отчасти муть, т.к. названия плавают от "кодировки" до "представления". Лучше ориентироваться на оригинальное название Unicode Transformation Format. Акцент - на втором слове. UTF-8 - формат представления символов Юникода, с переменным числом байт (от 1 до 4) UTF-16 - формат представления символов Юникода, с переменным числом байт (2 или 4) UTF-32 - формат представления символов Юникода, с постоянным числом байт 4 Характеристики UTF-8 - лучшая компактность в памяти, самый медленный парсинг буфера в глифы UTF-16 - средняя компактность в памяти, средний-быстрый по скорости парсинг буфера в глифы UTF-32 - худшая компактность в памяти, самый быстрый по скорости парсинг буфера в глифы Что касается венды - своем API она пользует UTF-16 (а если точнее - UTF-16LE). Таким образом, если при проектировании ориентироваться на UTF-8, то наиболее частыми преобразованиями, при использовании API Windows, будут двусторонние операции UTF8<-->UTF-16LE. А вот одно- битные ASCII варианты из API Windows - это уже анохронизм. Добавлено Цитата ЫукпШ @ Иллюзия думать, что "сейчас я запишу в Unicode-строку" русские, арабские и японские символы и увижу всё это на экране. Скорее всего, на экране будут кракозябры. Это - перпендикулярный вопрос Тут уже идет речь не о кодировках и/или форматах, а о полноте наборов (плоскостей) в конкретном Unicode-шрифте. Если мне память не изменяет, то самые полные наборы глифов - содержат шрифты семейства Note. Вики: Цитата Хотя формы записи UTF-8 и UTF-32 позволяют кодировать до 231 (2 147 483 648) кодовых позиций, было принято решение использовать лишь 1 112 064 для совместимости с UTF-16. Впрочем, даже и этого в данный момент более чем достаточно — в версии 13.0 используется всего 143 859 кодовых позиций. Кодовое пространство разбито на 17 плоскостей (англ. planes) по 216 (65 536) символов. Нулевая плоскость (plane 0) называется базовой (basic) и содержит символы наиболее употребительных письменностей. Остальные плоскости — дополнительные (supplementary). Первая плоскость (plane 1) используется в основном для исторических письменностей, вторая (plane 2) — для редко используемых иероглифов китайского письма (ККЯ), третья (plane 3) зарезервирована для архаичных китайских иероглифов[66]. Плоскость 14 отведена для символов, используемых по особому назначению. Плоскости 15 и 16 выделены для частного употребления[7]. |
Сообщ.
#14
,
|
|
|
Цитата JoeUser @ Что касается венды - своем API она пользует UTF-16 (а если точнее - UTF-16LE). Таким образом, если при проектировании ориентироваться на UTF-8, то наиболее частыми преобразованиями, при использовании API Windows, будут двусторонние операции UTF8<-->UTF-16LE. А вот одно- битные ASCII варианты из API Windows - это уже анохронизм. Нет. Виндус не производит поддержку приложений UTF-8. Либо ASCII, либо UTF-16. Преобразование в UTF-8 полезно при обмене с linux-системами или при обработке linux-файлов. |
Сообщ.
#15
,
|
|
|
Цитата ЫукпШ @ Нет. Виндус не производит поддержку приложений UTF-8. Нет - зеленое! Где я говорил о поддержке UTF-8 виндой? Я сказал: Цитата ЫукпШ @ если при проектировании ориентироваться на UTF-8 Имеется ввиду твоей создаваемой программы. Добавлено Цитата ЫукпШ @ Преобразование в UTF-8 А хранение любых данных, для который некритична скорость парсинга (названия элементов управления UI, текстовое описание ошибок, сообщений & etc...) - лучше в UTF-8 из практических соображений. |