Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование Unicode, UTF-8, UTF-16, utf и иже с ним 
:(
    Опции темы
Emura
Дата 22.4.2009, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 7.2.2009

Репутация: 1
Всего: 1



Возникли непонятки с использованием unicode и как следствие c utf. по поиску в темах одни куски информации. более полного и внятного изложения не нашел. есть желание разобраться в вопросе. первый пост планирую дополнять полученной информацией.
 
для начала

1.
Код

#include <tchar.h>
//...
int WINAPI _tWinMain(..)
//...


2. в настройках проекта "Character Set" сменить на "Use Unicode Character Set"

3. строки в коде обрамлять макросом  _T("строка")


Текущие вопросы: 
-какой тип данных для строк использовать предпочтительней? (TCHAR, std::wstring или другое ) а главное удобнее
-можно ли использовать TEXT("строка") ?



Это сообщение отредактировал(а) Emura - 23.4.2009, 00:42
PM   Вверх
GremlinProg
Дата 22.4.2009, 19:23 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(Emura @  22.4.2009,  19:18 Найти цитируемый пост)

#define UNICODE
#define _UNICODE

так лучше не делать, это просто делает невозможным смену типа проекта из его настроек (можно назвать этот способ "в лоб")
Цитата(Emura @  22.4.2009,  19:18 Найти цитируемый пост)
в настройках проекта "Character Set" сменить на "Use Unicode Character Set"

идеальный способ
Цитата(Emura @  22.4.2009,  19:18 Найти цитируемый пост)
строки в коде обрамлять макросом  _T("строка")

этот макрос нужно использовать повсюду, на что распространяется влияние пункта 2,, т.е. независимо от того, UNICODE приложение или ANSI
Цитата(Emura @  22.4.2009,  19:18 Найти цитируемый пост)
какой тип данных для строк использовать предпочтительней? (TCHAR, std::wstring или другое ) а главное удобнее

проще всего пользоваться одним видом трансляции: и глазу приятно и мозг не перегружен
из постоянных - это макрос _T(x) и тип данных _TCHAR
все транслируемые CRT-функции имеют так же префикс _t,
который переводит их в 2 группы с префиксами mbs и wcs, что соответственно означает multi byte string(байтовые строки char) и wide char string(широкосимвольные строки wchar_t)

Цитата(Emura @  22.4.2009,  19:18 Найти цитируемый пост)
можно ли использовать TEXT("строка") ?

конечно можно
два макроса: _T(x) и TEXT(x) - идентичны
разница между ними только в том, что первый включен в tchar.h, а второй - в WinNT.h,
что соответственно, и определяет, какой из них доступен в данный момент (если подключается и windows.h и tchar.h, то ограничений нет - пользуй что хочешь)

Добавлено через 5 минут и 30 секунд
Цитата(GremlinProg @  22.4.2009,  21:23 Найти цитируемый пост)
этот макрос нужно использовать повсюду, на что распространяется влияние пункта 2, т.е. независимо от того, UNICODE приложение или ANSI

в принципе, _T можно и не использовать, но тогда по-хорошему, чтобы не было проблем, нужно настраивать кодировку проекта, используя лобовой метод (пункт 1)

тогда, чтобы не было проблем, этот метод нужно расширить:

установка ANSI:
Код

#if defined(_UNICODE)
#undef _UNICODE
#endif
#if defined(UNICODE)
#undef UNICODE
#endif

установка UNICODE:
Код

#if !defined(_UNICODE)
#define _UNICODE
#endif
#if !defined(UNICODE)
#define UNICODE
#endif



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Emura
Дата 23.4.2009, 01:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 7.2.2009

Репутация: 1
Всего: 1



спасибо за уточнения!

тогда от способа в лоб отказываемся тк он лишний, указываем Character Set через настройки проекта.
и в коде используем _T("строка")

Цитата

проще всего пользоваться одним видом трансляции: и глазу приятно и мозг не перегружен
из постоянных - это макрос _T(x) и тип данных _TCHAR
все транслируемые CRT-функции имеют так же префикс _t,
который переводит их в 2 группы с префиксами mbs и wcs, что соответственно означает multi byte string(байтовые строки char) и wide char string(широкосимвольные строки wchar_t)


_TCHAR и TCHAR в чем суть префикса "_" ? smile 

чтобы быстрее разобраться буду стараться задавать конкретные вопросы smile
планирую:
1) использовать UTF в самописных компонентах (принимать при вводе, для локализации и тп).
2) сохранять UTF в файл и читать от туда, запись осуществлять по-байтово.


ps. читаю попутно ФАКи



Это сообщение отредактировал(а) Emura - 23.4.2009, 02:41
PM   Вверх
GremlinProg
Дата 23.4.2009, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(Emura @  23.4.2009,  03:28 Найти цитируемый пост)
_TCHAR и TCHAR в чем суть префикса "_" ?

суть все в том же:
_TCHAR объявлен в tchar.h, а CHAR - в WinNT.h
_ - для разделения типов, поскольку typedef уже генерирует новый тип, т.е. чтобы не было неоднозначности при подключении обоих файлов в один проект; оба идентично определяют транслируемый тип данных char и wchar_t

правило в принципе очевидно:
все, что с префиксом _ - из tchar.h
все, что без него - из WinNT.h

это так же касается и использования самих макосов трансляции: UNICODE и _UNICODE

Добавлено через 11 минут и 50 секунд
Цитата(Emura @  23.4.2009,  03:28 Найти цитируемый пост)
тогда от способа в лоб отказываемся тк он лишний

иногда приложение требуется писать только в одной кодировке, причины могут быть разные: отсутствие поддержки какого-нибудь API UNICODE, или наоборот - ANSI, проблемы с русскими кодировками, и т.п., поэтому, чтобы не вводить в заблуждение остальных участников проекта, следует этот момент четко зафиксировать в коде,

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

Добавлено через 13 минут и 7 секунд
этот метод можно просто переместить в самый конец, как "случай на крайний случай" )


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
GremlinProg
Дата 23.4.2009, 12:22 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(Emura @  22.4.2009,  19:18 Найти цитируемый пост)
std::wstring

для std::string и std::wstring нет транслятора, поэтому, при их использовании следует написать транслятор, например такой:
Код

#if defined(_UNICODE)
  #define _tstring  wstring
#else
  #define _tstring  string
#endif

и, соответственно, использовать std::_tstring

либо аналогично объявить typedef для _tstring
либо использовать их применительно к частным случаям: в функциях с префиксами mbs и wcs, или с постфиксом A и W в API, соответственно


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Emura
Дата 23.4.2009, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 7.2.2009

Репутация: 1
Всего: 1



GremlinProg, спасибо, с _t уяснил.

1) std::wstring и WCHAR - в чем существенные отличия и что использовать удобнее? 
2)  в каких случаях может потребоваться конвертировать WCHAR в multi byte? 
3) в каких случаях может потребоваться работа с LPTSTR ?
4) как определить длину для TCHAR ? (lstrlen ?) подозреваю что нужна функция с префиксом _t (но не нашел)

Код

2) сохранять UTF в файл и читать от туда, запись осуществлять по-байтово.

GremlinProg, направь пожалуйста - какая должна быть последовательность(логика) действий для данной задачи.



Это сообщение отредактировал(а) Emura - 23.4.2009, 14:38
PM   Вверх
GremlinProg
Дата 23.4.2009, 17:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(Emura @  23.4.2009,  16:38 Найти цитируемый пост)
сохранять UTF в файл и читать от туда, запись осуществлять по-байтово.

http://forum.vingrad.ru/index.php?showtopi...t&p=1832431
тут одновременная поддержка 4-х кодировок, одна из которых - ANSI, остальные двухбайтовые
чтение осуществляется посимвольно (исходя из установок _UNICODE)
побайтово это делать не нужно
смотри пример
по крайней мере, чтение шаблона должно быть понятно
можно конечно выделить:
Код

    // определение размера поля BOM
    bomlen    = ftell(input);
    // определение числа символов в файле
    for(len = 0; !feof(input) ;_fgettc(input),++len);
    // распределение буфера под содержимое файла
    lpszBuffer        = (LPTSTR)malloc( (len + 1) * sizeof(_TCHAR) );
    // завершение буфера нуль-терминатором
    lpszBuffer[len]    = _T('\0');
    // перемещение файлового указателя к первому символу
    fseek(input,bomlen,SEEK_SET);
    // чтение файла в распределенный буфер
    for(std_out = 0,lpCh = lpszBuffer; !feof(input) ;*(lpCh++) = _fgettc(input));

Цитата(Emura @  23.4.2009,  16:38 Найти цитируемый пост)
как определить длину для TCHAR ? (lstrlen ?) подозреваю что нужна функция с префиксом _t (но не нашел)

_tcslen
строковые CRT-функции все здесь: http://msdn.microsoft.com/en-us/library/f0151s4x(VS.80).aspx
к любой функции в MSDN есть табличка Generic-Text Routine Mappings, в ней как раз все алиасы для нее и определены
пример таблицы:
Цитата

TCHAR.H routine    _UNICODE & _MBCS not defined    _MBCS defined  _UNICODE defined 
_tcscoll    strcoll     _mbscoll  wcscoll

Цитата(Emura @  23.4.2009,  16:38 Найти цитируемый пост)
в каких случаях может потребоваться работа с LPTSTR 

LPTSTR - это ни что иное как _TCHAR*, соответственно, и требуется он так же, при трансляции _UNICODE
Цитата(Emura @  23.4.2009,  16:38 Найти цитируемый пост)
в каких случаях может потребоваться конвертировать WCHAR в multi byte? 

в случаях, когда нужна байтовая строка: char*, а имеется WCHAR*
Цитата(Emura @  23.4.2009,  16:38 Найти цитируемый пост)
 std::wstring и WCHAR - в чем существенные отличия и что использовать удобнее?

сравнивать их нет смысла
std::wstring - строковый буфер
единственное, что у них общего - тип символа WCHAR

Добавлено через 12 минут и 57 секунд
если поддержка ANSI-файлов не предполагается, то можно работать и так:
Код

    std::wstring buffer;
    WCHAR*lpCh;
    // определение размера поля BOM
    bomlen    = ftell(input);
    // определение числа символов в файле
    for(len = 0; !feof(input) ;fgetwc(input),++len);
    // распределение буфера под содержимое файла
    if( len ){
        buffer.resize(len);
        // перемещение файлового указателя к первому символу
        fseek(input,bomlen,SEEK_SET);
       // чтение файла в распределенный буфер
        for(lpCh = &*buffer.begin(); !feof(input) ;*(lpCh++) = fgetwc(input));
    }



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Emura
Дата 23.4.2009, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 7.2.2009

Репутация: 1
Всего: 1



GremlinProg, большое спасибо за разъяснения. буду разбираться.
PM   Вверх
GremlinProg
Дата 23.4.2009, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



незачто, у тебя правильный подход к систематизации знаний,
и правильные вопросы
за это тебе +1
Цитата(Emura @  23.4.2009,  16:38 Найти цитируемый пост)
std::wstring и WCHAR - в чем существенные отличия и что использовать удобнее

удобнее использовать конечно STL-контейнеры, в данном случае std::wstring, std::string


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Emura
Дата 24.4.2009, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 7.2.2009

Репутация: 1
Всего: 1



Цитата

незачто, у тебя правильный подход к систематизации знаний,
и правильные вопросы


спасибо! скоро правильных вопросов по кодировке будет еще больше smile еще не подошел к ним в плотную.

пс. я с c# перешел на с++ (на c# с php  smile ). в c# много удобств наделали, но в c++ больше свободы и независимость от net само собой. правда все удобства приходится создавать самому.. на что тратиться уйма не лишнего времени. зато потом это должно, точнее просто обязано оправдаться.... smile

Это сообщение отредактировал(а) Emura - 24.4.2009, 15:15
PM   Вверх
Emura
Дата 28.4.2009, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 7.2.2009

Репутация: 1
Всего: 1



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

Код

 _tcscmp(s1.c_str(),s2.c_str())

//или  

lstrcmp(s1.c_str(),s2.c_str())


s1 и s2 могут быть как std::string так и std::wstring. на данный момент ориентируюсь на wstring.
может для пущей точности использовать и то и то? что посоветуете?


Это сообщение отредактировал(а) Emura - 28.4.2009, 13:08
PM   Вверх
GremlinProg
Дата 28.4.2009, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



без разницы, обе функции делают одно и то же
разница может быть только если локаль потока отличается от локали CRT:
первая функция использует локаль CRT: setlocale
вторая функция использует локаль потока, в котором она вызывается: GetThreadLocale
(хотя локаль CRT может сама синхронизироваться с локалью потока, не проверял, но в таком случае, результаты работы обеих функций будут уже абсолютно идентичны)
Цитата(Emura @  28.4.2009,  15:07 Найти цитируемый пост)
может для пущей точности использовать и то и то? что посоветуете?

для большей гарантии в работоспособности, лучше использовать что-то одно, не надо смешивать

Добавлено через 2 минуты и 38 секунд
Цитата(Emura @  28.4.2009,  15:07 Найти цитируемый пост)
s1 и s2 могут быть как std::string так и std::wstring. на данный момент ориентируюсь на wstring

не надо смешивать так же _t-функции с wcs-данными, и наоборот

Добавлено через 3 минуты и 29 секунд
Цитата(GremlinProg @  28.4.2009,  15:50 Найти цитируемый пост)
с wcs-данными

с wcs- и mbs-данными


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Emura
Дата 28.4.2009, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 7.2.2009

Репутация: 1
Всего: 1



ок, спасибо за совет.

Цитата

не надо смешивать так же _t-функции с wcs-данными, и наоборот


GremlinProg, не понял замечания, ведь _tcscmp расширяется в strcmp и в wcscmp. а если это про то, что wstring строковый буфер это я усвоил smile
PM   Вверх
GremlinProg
Дата 28.4.2009, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(Emura @  28.4.2009,  16:03 Найти цитируемый пост)
а если это про то, что wstring строковый буфер это я усвоил

я про то, что явное использование std::wstring и std::string уже не желательно с функциями _t
правильно, еси они используются неявно, т.е. через транслятор: http://forum.vingrad.ru/index.php?showtopi...t&p=1850432


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Emura
Дата 28.4.2009, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 7.2.2009

Репутация: 1
Всего: 1



GremlinProg, да да да, именно этой политике я и придерживаюсь smile 
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1234 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.