Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Системное программирование и WinAPI > Использование Unicode, UTF-8, UTF-16 |
Автор: Emura 22.4.2009, 17:18 | ||
Возникли непонятки с использованием unicode и как следствие c utf. по поиску в темах одни куски информации. более полного и внятного изложения не нашел. есть желание разобраться в вопросе. первый пост планирую дополнять полученной информацией. для начала 1.
2. в настройках проекта "Character Set" сменить на "Use Unicode Character Set" 3. строки в коде обрамлять макросом _T("строка") Текущие вопросы: -какой тип данных для строк использовать предпочтительней? (TCHAR, std::wstring или другое ) а главное удобнее -можно ли использовать TEXT("строка") ? |
Автор: Emura 23.4.2009, 01:28 | ||
спасибо за уточнения! тогда от способа в лоб отказываемся тк он лишний, указываем Character Set через настройки проекта. и в коде используем _T("строка")
_TCHAR и TCHAR в чем суть префикса "_" ? ![]() чтобы быстрее разобраться буду стараться задавать конкретные вопросы ![]() планирую: 1) использовать UTF в самописных компонентах (принимать при вводе, для локализации и тп). 2) сохранять UTF в файл и читать от туда, запись осуществлять по-байтово. ps. читаю попутно ФАКи |
Автор: GremlinProg 23.4.2009, 11:53 |
суть все в том же: _TCHAR объявлен в tchar.h, а CHAR - в WinNT.h _ - для разделения типов, поскольку typedef уже генерирует новый тип, т.е. чтобы не было неоднозначности при подключении обоих файлов в один проект; оба идентично определяют транслируемый тип данных char и wchar_t правило в принципе очевидно: все, что с префиксом _ - из tchar.h все, что без него - из WinNT.h это так же касается и использования самих макосов трансляции: UNICODE и _UNICODE Добавлено через 11 минут и 50 секунд иногда приложение требуется писать только в одной кодировке, причины могут быть разные: отсутствие поддержки какого-нибудь API UNICODE, или наоборот - ANSI, проблемы с русскими кодировками, и т.п., поэтому, чтобы не вводить в заблуждение остальных участников проекта, следует этот момент четко зафиксировать в коде, в таком случае и требуется метод "в лоб", т.е. он не лишний, просто требуется он крайне редко и не по делу его использовать не стоит, только когда реально невозможно поддержать в проекте обе ветки Добавлено через 13 минут и 7 секунд этот метод можно просто переместить в самый конец, как "случай на крайний случай" ) |
Автор: GremlinProg 23.4.2009, 12:22 | ||
для std::string и std::wstring нет транслятора, поэтому, при их использовании следует написать транслятор, например такой:
и, соответственно, использовать std::_tstring либо аналогично объявить typedef для _tstring либо использовать их применительно к частным случаям: в функциях с префиксами mbs и wcs, или с постфиксом A и W в API, соответственно |
Автор: Emura 23.4.2009, 14:38 | ||
GremlinProg, спасибо, с _t уяснил. 1) std::wstring и WCHAR - в чем существенные отличия и что использовать удобнее? 2) в каких случаях может потребоваться конвертировать WCHAR в multi byte? 3) в каких случаях может потребоваться работа с LPTSTR ? 4) как определить длину для TCHAR ? (lstrlen ?) подозреваю что нужна функция с префиксом _t (но не нашел)
GremlinProg, направь пожалуйста - какая должна быть последовательность(логика) действий для данной задачи. |
Автор: GremlinProg 23.4.2009, 17:42 | ||||||||||||||
http://forum.vingrad.ru/index.php?showtopic=253883&view=findpost&p=1832431 тут одновременная поддержка 4-х кодировок, одна из которых - ANSI, остальные двухбайтовые чтение осуществляется посимвольно (исходя из установок _UNICODE) побайтово это делать не нужно смотри пример по крайней мере, чтение шаблона должно быть понятно можно конечно выделить:
_tcslen строковые CRT-функции все здесь: http://msdn.microsoft.com/en-us/library/f0151s4x(VS.80).aspx к любой функции в MSDN есть табличка Generic-Text Routine Mappings, в ней как раз все алиасы для нее и определены пример таблицы:
LPTSTR - это ни что иное как _TCHAR*, соответственно, и требуется он так же, при трансляции _UNICODE
в случаях, когда нужна байтовая строка: char*, а имеется WCHAR*
сравнивать их нет смысла std::wstring - строковый буфер единственное, что у них общего - тип символа WCHAR Добавлено через 12 минут и 57 секунд если поддержка ANSI-файлов не предполагается, то можно работать и так:
|
Автор: Emura 23.4.2009, 17:56 |
GremlinProg, большое спасибо за разъяснения. буду разбираться. |
Автор: GremlinProg 23.4.2009, 18:14 | ||
незачто, у тебя правильный подход к систематизации знаний, и правильные вопросы за это тебе +1
удобнее использовать конечно STL-контейнеры, в данном случае std::wstring, std::string |
Автор: Emura 24.4.2009, 15:12 | ||
спасибо! скоро правильных вопросов по кодировке будет еще больше ![]() пс. я с c# перешел на с++ (на c# с php ![]() ![]() |
Автор: Emura 28.4.2009, 13:07 | ||
вот понадобилось сравнить две строки и задумался что использовать
s1 и s2 могут быть как std::string так и std::wstring. на данный момент ориентируюсь на wstring. может для пущей точности использовать и то и то? что посоветуете? |
Автор: GremlinProg 28.4.2009, 13:50 | ||
без разницы, обе функции делают одно и то же разница может быть только если локаль потока отличается от локали CRT: первая функция использует локаль CRT: setlocale вторая функция использует локаль потока, в котором она вызывается: GetThreadLocale (хотя локаль CRT может сама синхронизироваться с локалью потока, не проверял, но в таком случае, результаты работы обеих функций будут уже абсолютно идентичны) для большей гарантии в работоспособности, лучше использовать что-то одно, не надо смешивать Добавлено через 2 минуты и 38 секунд
не надо смешивать так же _t-функции с wcs-данными, и наоборот Добавлено через 3 минуты и 29 секунд с wcs- и mbs-данными |
Автор: Emura 28.4.2009, 14:03 | ||
ок, спасибо за совет.
GremlinProg, не понял замечания, ведь _tcscmp расширяется в strcmp и в wcscmp. а если это про то, что wstring строковый буфер это я усвоил ![]() |
Автор: GremlinProg 28.4.2009, 14:46 |
я про то, что явное использование std::wstring и std::string уже не желательно с функциями _t правильно, еси они используются неявно, т.е. через транслятор: http://forum.vingrad.ru/index.php?showtopic=256580&view=findpost&p=1850432 |
Автор: Emura 28.4.2009, 15:43 |
GremlinProg, да да да, именно этой политике я и придерживаюсь ![]() |
Автор: Emura 14.5.2009, 19:38 |
подскажите пожалуйста последовательность действий для следующей задачи. есть файл, текстовый в UTF-8. пытаюсь нарисовать его содержимое. с "нарисовать" думаю проблем нет, для этого нужен массив WCHAR. ...а вот как его извлеч из файла -призадумался чтото, хотя задача то вроде банальная. |
Автор: GremlinProg 14.5.2009, 19:47 | ||||
извлечь... я же давал алгоритм может что-то непонятно?
далее чтение: http://forum.vingrad.ru/index.php?showtopic=256580&view=findpost&p=1850770
lpszBuffer или buffer (там 2 способа), после этого будет содержать контент из UTF-8-файла |
Автор: Emura 14.5.2009, 20:04 | ||||
да-да, смотрел, но недопонял что-то, каша в голове от этих кодировок.. строк ![]() cейчас читаю файл в CHAR* так
может сначала прочитать в байты потом их конвертировать в CHAR или WCHAR?
GremlinProg, а есть еще варианты получить кол-во? |
Автор: GremlinProg 14.5.2009, 20:17 |
Emura, символ UTF-8 - не имеет постоянной длины (тут ANSI и UNICODE смешаны), только ради расчета числа символов, я и прохожу файл дважды: первый раз, чтобы получить число символов, перед распределением буфера второй раз, чтобы их считать можно не файл дважды проходить, можно проходить и буфер дважды, но сделать это придется в любом случае файл обойти проще, тем более, текстовый, тут особенно оптимизировать просто нет смысла и проще всего для этого использвать CRT-стримы (stream), а не файлы API (CreateFile), потому что эта задача в CRT уже решена, велосипед изобретать не надо |
Автор: Emura 14.5.2009, 20:29 | ||
ок, спасибо за советы. кстати, вот попробовал такое -рисует не потребное ![]()
|
Автор: GremlinProg 14.5.2009, 20:51 | ||
есть, но цикл все равно нужен:
lpszInput - байтовый буфер, в который предварительно считан файл причем тут нужно четко определить, имеется ли в файле BOM это поле идентифиуирует кодировку файла в целом для UTF-8, это первые 3 байта EF BB BF если они присутствуют, то их нужно обязательно либо пропустить, либо вообще выбросить все это уже делает _tfopen_s, без нее - проверяй вручную, но перед инициализацией переменной file |
Автор: GremlinProg 14.5.2009, 21:23 |
нет, похоже так не получится тут нужно еще указать кодировку в переменной file а в CRT она ассоциируется похоже только с файловым дескриптором так что только читать файл, либо переводить байты напрямую, в юникод: BytesToUnicode |