Я вижу, что Visual Studio 2008 и позже теперь начинается новое решение с набором Набора символов к Unicode. Мой старый код C++ имеет дело только с английским текстом ASCII и полон:
"Hello World"
char
ввестиchar *
указатели на выделенные струны доSTL string
ввестиПреобразования из STL string
к струне до и наоборот использованию STL string
конструктор (который принимает const char *
) и STL string.c_str()
Каковы изменения, которые я должен внести для миграции этого кода так, чтобы он работал в экосистеме Unicode Visual Studio, и Unicode включил библиотеки? (У меня нет реальной потребности в нем, работают и с ASCII и с Unicode, это может быть чистый Unicode.)
Также возможно сделать это независимым от платформы способом? (т.е. не используя типы Microsoft.)
Я вижу так многих широкий символ и типы Unicode и преобразования, рассеянные вокруг, следовательно мой беспорядок. (Исключая: wchar_t, TCHAR, _T, _TEXT, ТЕКСТ и т.д.)
"Hello World" -> L "Hello World"
char -> wchar_t (если только вы на самом деле не хотите char)
char * -> wchar_t *
string -> wstring
Они все независимы от платформы. Однако, имейте в виду, что широкий символ может быть разным на разных платформах (два байта на Windows, четыре байта на других).
Определите UNICODE и _UNICODE в своем проекте (в Visual Studio это можно сделать, настроив проект на использование Unicode в настройках). Это также сделает макросы _T, TCHAR, _TEXT и TEXT автоматическими L. Они специфичны для Microsoft, поэтому избегайте их, если хотите быть кроссплатформенным.
CHAR
с макросами Char
, то все должно работать.
Я очень рекомендую против L""
, _T()
, std::wstring
(последнее не является мультиплатформенным) и рекомендаций Майкрософт о том, как выполнять Юникод.
В этом вопросе много путаницы. Некоторые до сих пор думают, что Юникод == 2 байтных символа == UTF-16. Ни то, ни другое равенство не является правильным.
На самом деле, это возможно , и даже лучше остаться с char* и обычным std::string
, обычными литералами и изменять очень мало (и все еще полностью поддерживать Юникод!).
Смотрите мой ответ здесь: https://stackoverflow.com/questions/1049947/should-utf-16-be-considered-harmful/1855375#1855375, как сделать это самым простым (на мой взгляд) способом.
Ваш вопрос связан с двумя разными, но связанными концепциями. Один из них - кодирование строки (например, Unicode / ASCII). Другой - тип данных, который будет использоваться для представления символов.
Технически вы можете иметь приложение Unicode с использованием простого Char
и STD :: String. Вы можете использовать литералы в шестнадцатеричном формате («\ x5fa») или октал («\ 05FA»), чтобы указать последовательность байтов строки. Обратите внимание, что с этим подходом ваши уже существующие строковые литералы, содержащие символы ASCII, должны оставаться действительными, поскольку Unicode сохраняет коды из ASCII.
Одним из важных точек зрения является то, что многие функции, связанные с строками, должны использоваться тщательно. Это потому, что они будут работать на байтах , а не символов . Например, STD :: string :: Оператор []
может дать вам определенный байт, который является только частью символа Unicode.
В Visual Studio WHAR_T
был выбран в качестве основного типа символа. Поэтому, если вы работаете с библиотеками на основе Microsoft, вещи должны быть легче для вас, если вы будете следовать многим советам, размещенным другими здесь. Замена CHAR
для для wchar_t
, используя макросы «T» (если вы хотите сохранить прозрачность между Unicode / Non-Unicode) и т. Д.
Однако я не думаю Существует де-факто стандарт работы с Unicode по библиотекам, поскольку они могут иметь разные стратегии для его решения.
Я бы предложил не беспокоиться о поддержке как ASCII, так и Unicode Build (A-La Tchar) и пойти на большую часть к Unicode. Таким образом, вы можете использовать больше функций независимых функций платформы (WCSCPY, WCSSTR и т. Д.) Вместо того, чтобы полагаться на функции tchar
, которые являются специфическими к Micrpsoft.
Вы можете использовать std :: wstring вместо std :: string и заменить все char
с wchar_t
s. С массовым изменением, таким образом, я обнаружил, что вы начнете с одной вещи и позвольте компилятору направлять вас к следующему.
Одно то, что я могу думать о том, что может быть не очевидно во время выполнения, - это то, где строка выделяется Malloc без использования SizeOf
оператора для базового типа. Так что следите за такими вещами, как CHAR * P = (CHAR *) MALLOC (11)
- 10 символов плюс завершается нуль, эта строка будет половина размера, который он должен быть в WHAR_T
с. Он должен стать wchar_t * p = (wchar_t *) malloc (11 * sizeof (wchar_t))
.
Ох и весь tchar
- поддерживать строки времени с компиляцией ASCII / Unicode. Он определил что-то вроде этого:
#ifdef _UNICODE
#define _T(x) L ## x
#else
#define _T(x) ## x
#endif
так, чтобы в конфигурации Unicode становится («бла»)
L «BLAH»
и в конфигурации ASCII это .