Как правильно использовать параметр компилятора charset -finput -в g++, чтобы скомпилировать исходный файл, отличный от -UTF -8?

Я пытаюсь скомпилировать исходный файл UTF -16BE C++ в g++ с параметром компилятора -finput -charset, но всегда получаю кучу ошибок. Более подробная информация приведена ниже.

Моя среда (в CentOS Linux):

  • г++ :4.1.2
  • iconv :2,5
  • Язык Linux (в Терминале ):LANG="en _US.UTF -8"

Мой образец исходного файла (, хранящийся в кодировке UTF -16BE ):

// main.cpp:

#include <iostream>

int main()
{
    std::cout << "Hello, UTF-16" << std::endl;
    return 0;
}

. Мои шаги:

  • Я прочитал руководство по g++ о опции кодировки -finput -. В руководстве по g++ сказано:

-finput-charset=charset Set the input character set, used for translation from the character set of the input file to the source character set used by GCC. If the locale does not specify, or GCC cannot get this information from the locale, the default is UTF-8. This can be overridden by either the locale or this command line option. Currently the command line option takes precedence if there’s a conflict. charset can be any encoding supported by the system’s "iconv" library routine.

  • Таким образом, я ввел команду следующим образом:

g++ -finput-charset=UTF-16BE main.cpp

и я получил эти ошибки:

In file included from main.cpp:1:

/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/iostream:1: error: stray ‘\342’ in program

/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/iostream:1: error: stray ‘\274’ in program

...(repeatedly, A LOT, around 4000+)...

/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/iostream:1: error: stray ‘\257’ in program

main.cpp: In function ‘int main()’:

main.cpp:5: error: ‘cout’ is not a member of ‘std’

main.cpp:5: error: ‘endl’ is not a member of ‘std’

  • Текст руководства предполагает, что набор символов может быть любой кодировкой, поддерживаемой подпрограммой iconv, поэтому я предположил, что ошибки компиляции могут быть вызваны моей библиотекой iconv. Затем я протестировал iconv:

iconv --from-code=UTF-16BE --to-code=UTF-8 --output=main_utf8.cpp main.cpp

Файл «main _utf8.cpp» создается, как и ожидалось. Затем я попытался его скомпилировать:

g++ -finput-charset=UTF-8 main_utf8.cpp

Обратите внимание, что я явно указал входную кодировку -, чтобы убедиться, что я сделал что-то не так, но на этот раз «a.out» был сгенерирован без каких-либо ошибок. Когда я запустил его, он мог выдать правильный вывод.

Наконец...

Я не мог понять, где я ошибся. Я искал в Интернете несколько примеров для этой опции компилятора, но не смог.

Пожалуйста, порекомендуйте! Спасибо!

Дальнейшие правки:

Спасибо ребята! Ваши ответы быстрые! Некоторые обновления:

  1. Когда я сказал «UTF -16», я имел в виду «UTF -16 + BOM». На самом деле я использовал UTF -16BE. Я обновил текст выше.
  2. В некоторых ответах говорится, что ошибки вызваны файлами заголовков, отличными от -UTF -16. Вот что я думаю, если это так :Мы всегда будем включать некоторые стандартные заголовочные файлы при написании проекта C/C++, верно? Например, stdio.h или iostream. Если компилятор G++ имеет дело только с кодировкой исходных файлов, созданных нами, но никогда с исходными файлами в стандартной библиотеке, то для чего существует эта опция -finput -charset??

Окончательное редактирование:

Наконец, мое решение выглядит так:

  1. В начале я изменил кодировку моих исходных файлов на GB2312, как сказал «мистер Листер» ниже. Некоторое время это работало нормально, но позже я обнаружил, что это не подходит для моей ситуации, потому что большинство других частей системы по-прежнему используют UTF -8 для связи и интерфейсов, поэтому я должен преобразовать кодировку во многих местах... Это не только накладные расходы на мою работу, но и может привести к некоторому снижению производительности моей программы.
  2. Позже я попытался преобразовать все свои исходные файлы в UTF -8 + BOM. Таким образом, Visual Studio в Windows могла бы их успешно скомпилировать, но GCC в Linux будет жаловаться. Затем я написал сценарий оболочки для удаления спецификации, и прежде чем я захочу скомпилировать свой код с помощью GCC, я сначала запускаю этот сценарий.
  3. К счастью, мне не нужно собирать код в Linux вручную, потому что TeamCity, инструмент непрерывной интеграции, используется в моем проекте для автоматического создания сборки. Я мог бы изменить шаги сборки в TeamCity, чтобы помочь мне запустить этот скрипт до начала ежедневной сборки.
  4. С помощью этого метода UTF -8 + BOM + script я решаю не редактировать свой исходный код в Linux, потому что, если я хочу это сделать, я должен убедиться, что мой код может быть успешно собран, прежде чем я его зафиксирую, что означает, что я должен запустите сценарий для удаления спецификации, прежде чем я создам код, что означает, что SVN будет сообщать о КАЖДОМ файле, который изменен (спецификация удалена ), таким образом, очень легко ошибочно зафиксировать неправильный файл. Чтобы решить эту проблему,Я написал еще один сценарий оболочки, чтобы добавить спецификацию обратно в исходные файлы. Хотя я до сих пор не очень часто редактирую свой код в Linux, но когда мне это действительно нужно, мне не приходится сталкиваться с ужасно длинным списком изменений в диалоговом окне фиксации.
7
задан yaobin 26 June 2012 в 12:33
поделиться