TCHAR все еще актуален?
Вопрос
Я новичок в программировании для Windows, и после прочтения книги Петцольда мне интересно:
все же рекомендуется использовать тип TCHAR
и функцию _T ()
для объявления строк или если мне просто нужно использовать wchar_t
и L "
строки в новом коде?
Я буду ориентироваться только на Windows 2000 и выше, и мой код с самого начала будет i18n . р>
Решение
Я бы все еще использовал синтаксис TCHAR, если бы сегодня делал новый проект. Между его использованием и синтаксисом WCHAR нет большой практической разницы, и я предпочитаю код, который явно указан в типе символа. Поскольку большинство функций API и вспомогательных объектов принимают / используют типы TCHAR (например, CString), имеет смысл использовать его. Кроме того, это дает вам гибкость, если вы решите использовать код в приложении ASCII в какой-то момент или если Windows когда-либо перейдет на Unicode32 и т. Д.
Если вы решите пойти по пути WCHAR, я бы прямо об этом сказал. То есть используйте CStringW вместо CString и применяйте макросы при преобразовании в TCHAR (например, CW2CT).
Во всяком случае, это мое мнение.
Другие советы
Краткий ответ: НЕТ .
Как и все другие, уже написанные, многие программисты все еще используют TCHAR и соответствующие функции. По моему скромному мнению, вся концепция была плохой идеей . UTF-16 обработка строк во многом отличается от простой строки ASCII / MBCS обработка. Если вы используете одни и те же алгоритмы / функции с ними обоими (именно на этом основана идея TCHAR!), Вы получите очень плохую производительность в версии UTF-16, если вы делаете немного больше, чем простая конкатенация строк (например, разбор и т. д.). Основной причиной являются суррогаты .
За единственным исключением, когда вы действительно должны скомпилировать свое приложение для системы, которая не поддерживает Unicode, я не вижу причин использовать этот багаж из прошлого в новом приложении.
Я должен согласиться с Сашей. Основная предпосылка TCHAR
/ _T ()
/ и т. Д. Состоит в том, что вы можете написать приложение на основе «ANSI» и затем волшебным образом предоставить ему поддержку Unicode, определив макрос , Но это основано на нескольких плохих предположениях:
что вы активно создаете версии своего программного обеспечения для MBCS и Unicode
В противном случае вы будете проскальзывать и использовать обычные строки char *
во многих местах.
То, что вы не используете экранирование без обратной ASCII в литералах _T (" ... ")
Если ваш " ANSI " кодировка соответствует ISO-8859-1, результирующие литералы char *
и wchar_t *
не будут представлять одинаковые символы.
То, что строки UTF-16 используются точно так же, как " ANSI " строки
Это не так. Юникод вводит несколько концепций, которых нет в большинстве устаревших кодировок символов. Суррогаты. Сочетание персонажей. Нормализация. Условные и языковые правила обсадных труб.
И, возможно, самое главное, тот факт, что UTF-16 редко сохраняется на диске или отправляется через Интернет: UTF-8 имеет тенденцию быть предпочтительным для внешнего представления.
То, что ваше приложение не использует Интернет
(Теперь это может быть допустимым предположением для вашего программного обеспечения, но ...)
Сеть работает на UTF-8 и множество более редких кодировок . Концепция TCHAR
распознает только два: " ANSI " (который не может быть UTF-8 ) и "Unicode" (UTF-16). Это может быть полезно для того, чтобы ваши вызовы Windows API поддерживали Unicode, но чертовски бесполезны для того, чтобы ваши веб-приложения и приложения электронной почты могли поддерживать Unicode.
То, что вы не используете библиотеки сторонних разработчиков
Никто другой не использует TCHAR
. Poco использует std :: string
и UTF-8. SQLite имеет версии API для UTF-8 и UTF-16, но нет TCHAR
, TCHAR
отсутствует даже в стандартной библиотеке, поэтому нет std :: tcout
, если вы не хотите определить его самостоятельно.
Что я рекомендую вместо TCHAR
Забудь, что " ANSI " Существуют кодировки, за исключением случаев, когда вам нужно прочитать файл, который не является допустимым UTF-8. Забудьте и о TCHAR
. Всегда звоните "W" версия функций Windows API. #define _UNICODE
, чтобы убедиться, что вы случайно не вызвали " A " функция. р>
Всегда используйте кодировки UTF для строк: UTF-8 для строк char
и UTF-16 (в Windows) или UTF-32 (в Unix-подобных системах) для wchar_t
Струны. typedef
UTF16
и UTF32
, чтобы избежать различий между платформами.
Если вам интересно, по-прежнему ли это на практике, то да - он все еще используется довольно часто. Никто не посмотрит на ваш код смешно, если он использует TCHAR и _T (" "). Проект, над которым я сейчас работаю, - это преобразование из ANSI в Unicode, и мы собираемся использовать переносной (TCHAR) маршрут.
Однако ...
Моим голосом было бы забыть все переносимые макросы ANSI / UNICODE (TCHAR, _T (" "), а также все вызовы _tXXXXXX и т. д. ...) и просто использовать unicode везде. Я действительно не вижу смысла в переносимости, если вам никогда не понадобится версия ANSI. Я бы использовал все функции и типы широких символов напрямую. Предварительно предваряйте все строковые литералы символом L.
Введение в статью по программированию Windows на MSDN говорит
Новые приложения всегда должны вызывать версии Unicode (API).
Макросы TEXT и TCHAR сегодня менее полезны, поскольку все приложения должны использовать Юникод.
Я бы придерживался wchar_t
и L "
.
Я хотел бы предложить другой подход (ни один из двух).
Подводя итог, используйте char * и std :: string, предполагая кодировку UTF-8, и выполняйте преобразования в UTF-16 только при переносе функций API.
Дополнительную информацию и обоснование этого подхода в программах Windows можно найти в http://www.utf8everywhere.org .
TCHAR
/ WCHAR
может быть достаточно для некоторых устаревших проектов. Но для новых приложений я бы сказал НЕТ .
Все эти TCHAR
/ WCHAR
есть по историческим причинам. TCHAR
предоставляет, по-видимому, аккуратный способ (маскировка) для переключения между кодировкой текста ANSI (MBCS) и кодировкой текста Unicode (UTF-16). В прошлом у людей не было понимания количества символов всех языков мира. Они предполагали, что 2 байта было достаточно для представления всех символов и, таким образом, имели схему кодирования символов фиксированной длины с использованием WCHAR
. Однако это уже не так после выпуска Unicode 2.0 в 1996 .
То есть:
Независимо от того, что вы используете в CHAR
/ WCHAR
/ TCHAR
, часть обработки текста в вашей программе должна обрабатывать переменную длину символы для интернационализации.
Таким образом, вам действительно нужно сделать больше, чем выбрать один из CHAR
/ WCHAR
/ TCHAR
для программирования в Windows:
WCHAR
. Так как этот способ проще работать с WinAPI с поддержкой Unicode. Посетите этот замечательный веб-сайт для более глубокого чтения: http://utf8everywhere.org/
Да, абсолютно; по крайней мере для макроса _T. Хотя я не очень уверен насчет широких символов.
Причина в том, что лучше поддерживать WinCE или другие нестандартные платформы Windows. Если вы на 100% уверены, что ваш код останется в NT, тогда вы, вероятно, можете просто использовать обычные объявления C-строк. Тем не менее, лучше стремиться к более гибкому подходу, так как гораздо проще #define этот макрос на платформе, отличной от Windows, по сравнению с прохождением тысяч строк кода и добавлением его везде, если вам нужно портировать какую-то библиотеку в Windows Mobile.
ИМХО, если в вашем коде есть TCHAR, вы работаете на неправильном уровне абстракции.
Используйте любой строковый тип, наиболее удобный для вас при работе с текстовой обработкой - надеюсь, это будет что-то, поддерживающее юникод, но это зависит от вас. При необходимости выполняйте преобразование на границах API ОС.
При работе с путями к файлам вместо использования строк создайте свой собственный тип. Это позволит вам независимые от ОС разделители путей, даст вам более простой интерфейс для кодирования, чем ручная конкатенация и разбиение строк, и будет намного легче адаптироваться к различным ОС (ansi, ucs-2, utf-8, что угодно) . р>
Единственными причинами, по которым я вижу использование чего-либо кроме явного WCHAR, являются мобильность и эффективность.
Если вы хотите, чтобы ваш окончательный исполняемый файл был как можно меньшего размера, используйте char.
Если вы не заботитесь об использовании оперативной памяти и хотите, чтобы интернационализация была такой же простой, как и простой перевод, используйте WCHAR. Р>
Если вы хотите сделать свой код гибким, используйте TCHAR.
Если вы планируете использовать только латинские символы, вы также можете использовать строки ASCII / MBCS, чтобы вашему пользователю не требовалось столько ОЗУ.
Для людей, которые «i18n с самого начала», сохраните пространство исходного кода и просто используйте все функции Unicode.
Просто добавляю к старому вопросу:
НЕТ
Начните новый проект CLR C ++ в VS2010. Сами Microsoft используют L " Hello World "
, - сказал nuff.