Вопрос

Я новичок в программировании для 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.
  • В противном случае я бы предложил использовать UTF-8 в качестве внутренней кодировки и хранить тексты в строках char или std :: string. И скрыть их в UTF-16 при вызове WinAPI. UTF-8 в настоящее время является доминирующей кодировкой, и существует множество удобных библиотек и инструментов для обрабатывать строки UTF-8.
  • Посетите этот замечательный веб-сайт для более глубокого чтения: 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.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top