Спецификация кодировки исходного кода в MSVC++, например, gcc -finput-charset=CharSet

Я хочу создать несколько примеров программ, которые имеют дело с кодировками, в частности, я хочу использовать широкие строки, например:

wstring a=L"grüßen";
wstring b=L"שלום עולם!";
wstring c=L"中文";

Потому что это примеры программ.

Это абсолютно тривиально с gcc, который обрабатывает исходный код как текст в кодировке UTF-8. Но прямая компиляция не работает под MSVC. Я знаю, что могу закодировать их с помощью escape-последовательностей, но я бы предпочел сохранить их в виде читаемого текста.

Есть ли какой-либо параметр, который я могу указать в качестве переключателя командной строки для «cl», чтобы это работало? Есть ли какой-нибудь переключатель командной строки, например gcc'c -finput-charset?

Если нет, как бы вы предложили сделать текст естественным для пользователя?

Примечание. добавление спецификации в файл UTF-8 не является вариантом, поскольку он становится некомпилируемым другими компиляторами.

Примечание 2. Мне нужно, чтобы он работал в версии MSVC >= 9 == VS 2008.

Настоящий ответ: решения нет


person Artyom    schedule 02.11.2009    source источник
comment
Удивительно, но MSVC++ не имеет такой опции компилятора. Какой позор...   -  person Piotr Dobrogost    schedule 14.03.2011
comment
Я предполагаю, что вы имели в виду спецификацию исходного кодировки файла, когда задавали этот вопрос. Исходная кодировка — это термин в стандарте, используемый для кодировки, определяемой реализацией, используемой внутри компилятора.   -  person Piotr Dobrogost    schedule 14.03.2011
comment
@PiotrDobrogost Можно только догадываться, почему Microsoft не догнала остальной мир, изначально поддерживая UTF-8 для компиляции и SDK, и добавляя так много неэффективности, хлопот, путаницы и страданий в жизни программистов, которые должны интернационализировать приложения Windows в мир UTF-8. Но у меня есть предположение; это называется бюрократия и движение прибыли выше заботы или заботы о качестве.   -  person Dan Nissenbaum    schedule 10.01.2015
comment
@DanNissenbaum Видите ли, MS намеренно не поддерживает UTF-8 или какую-либо реальную совместимость (термин, который они изобрели). Есть оооочень много мест, где MS просто портит вещи так, как это едва ли полезно. Так что либо МС так, либо никак.   -  person Artyom    schedule 11.01.2015


Ответы (5)


Для тех, кто придерживается девиза «лучше поздно, чем никогда», Visual Studio 2015 (версия 19 компилятора) теперь поддерживает это.

Новый переключатель командной строки /source-charset позволяет указать кодировку набора символов, используемую для интерпретации исходных файлов. Он принимает один параметр, который может быть либо IANA, либо Имя набора символов ISO:

/source-charset:utf-8

или десятичный идентификатор конкретной кодовой страницы (с предшествующей точкой):

/source-charset:.65001

Официальная документация находится здесь, а также a подробная статья с описанием этих новых параметров в блоге команды разработчиков Visual C++.

Существует также дополнительный /execution-charset переключатель, который работает точно так же, но управляет тем, как узкие символьные и строковые литералы генерируются в исполняемом файле. Наконец, есть переключатель быстрого доступа /utf-8, который устанавливает как /source-charset:utf-8, так и /execution-charset:utf-8.

Эти параметры командной строки несовместимы со старыми директивами #pragma setlocale и #pragma execution-character-set и применяются глобально ко всем исходным файлам.

Для пользователей, застрявших на более старых версиях компилятора, лучшим вариантом по-прежнему является сохранение исходных файлов в формате UTF-8 со спецификацией (как предлагалось в других ответах, среда IDE может сделать это при сохранении). Компилятор автоматически обнаружит это и будет вести себя соответствующим образом. То же самое и с GCC, который также принимает спецификацию в начале исходных файлов, не задыхаясь, что делает этот подход функционально переносимым.

person Cody Gray    schedule 10.06.2016

Откройте File->Advances Save Options... Выберите Unicode(UTF-8 with signature) - Codepage 65001 в списке кодировок. Компилятор автоматически использует выбранную кодировку.


Согласно ответу Microsoft здесь:

если вам нужны символы, отличные от ASCII, то «официальный» и портативный способ их получить - это использовать шестнадцатеричное кодирование \u (или \U) (что, я согласен, просто уродливо и подвержено ошибкам).

Когда компилятор сталкивается с исходным файлом, у которого нет спецификации, компилятор считывает файл на определенное расстояние вперед, чтобы увидеть, может ли он обнаружить какие-либо символы Unicode - он специально ищет UTF-16 и UTF-16BE - если это не так. t find также предполагает, что у него есть MBCS. Я подозреваю, что в этом случае он возвращается к MBCS, и это вызывает проблему.

Быть явным действительно лучше, поэтому, хотя я знаю, что это не идеальное решение, я бы предложил использовать спецификацию.

Джонатан Кейвс
Команда компилятора Visual C++.


Хорошим решением будет размещение текстовых строк в файлах ресурсов. Это удобный и портативный способ. Вы можете использовать библиотеки локализации, такие как gettext, для управления переводами.

person Kirill V. Lyadvinsky    schedule 02.11.2009
comment
Компилятор автоматически конвертирует строковые константы в файл, поэтому в результате строка будет сохранена в EXE с использованием кодировки UCS2. - person Kirill V. Lyadvinsky; 02.11.2009
comment
Хорошо, я понимаю, дело в том, что вы предлагаете вручную добавить метку BOM в UTF-8, и это действительно работает, но проблема не работает с gcc и другими компиляторами, которые не ожидают бессмысленной спецификации. - person Artyom; 02.11.2009
comment
Может быть, вам стоит попробовать UTF-16 без подписи. Visual C++ поддерживает это, а как насчет gcc? - person Kirill V. Lyadvinsky; 02.11.2009
comment
Нет... Также я предполагаю, что большинство компиляторов не могут - person Artyom; 02.11.2009
comment
Хорошо... Я вижу, что решения нет (отвечает MS). Спасибо за ссылку, принимаю ответ - person Artyom; 17.11.2009

Поток, который мы использовали: сохранить файлы как UTF8-с спецификацией, использовать один и тот же источник между linux и windows, для linux: предварительно обработать исходные файлы в команде компиляции, чтобы удалить спецификацию, запустить g++ в промежуточном файле, отличном от спецификации.

person Navit F    schedule 12.06.2012

Для VS вы можете использовать:

#pragma setlocale( "[locale-string]" )

В качестве кодировки файла будет использоваться кодовая страница ANSI по умолчанию для локали.

Но в целом плохая идея жестко закодировать любые строки, видимые пользователю, в вашем коде. Храните их в каких-то ресурсах. Хорошо подходит для локализации, легкой проверки орфографии и обновления и т. д.

person Mihai Nita    schedule 11.11.2009
comment
Но в целом плохая идея жестко закодировать любые видимые пользователю строки в вашем коде, который я знаю, но это в основном для примеров, когда такие вещи важны для пользователя, чтобы увидеть, что на самом деле происходит. Но как указать кодировку UTF-8 в строке локали? Насколько я знаю, Windows не поддерживает локали в кодировке UTF-8. - person Artyom; 11.11.2009
comment
После короткого теста MSVC 2005 не принимает setlocale(".65001"), то есть кодовую страницу UTF-8. - person Artyom; 11.11.2009
comment
65001 — это кодовая страница, прагма принимает локаль. Нет локалей с UTF-8 в качестве кодовой страницы. Если вам нужно, чтобы он работал только в VS, вы можете сохранить его как UTF-16 (из «Блокнота» «Сохранить как» и выбрать кодировку Unicode). Единственный переносимый способ сделать это в противном случае - избежать его, как предложил Шервуд Ху. Нравится вам это или нет, но это единственный путь. И правильный способ - не жестко кодировать это в вашем файле c :-) - person Mihai Nita; 15.11.2009

ИМХО, все исходные файлы C++ должны быть в строгом формате ASCII. Комментарии могут быть в UTF-8, если редактор поддерживает это.
Это делает код переносимым между платформами, редакторами и системами управления версиями.

Вы можете использовать \u для вставки символов Unicode в широкую строку:

std::wstring str = L"\u20AC123,00"; //€123,00
person cuteCAT    schedule 12.11.2009
comment
Вот чего я точно не хочу делать - person Artyom; 12.11.2009