-finput-charset コンパイラ オプションを使用して g++ で UTF-16BE C++ ソース ファイルをコンパイルしようとしていますが、常に多くのエラーが発生します。詳細は次のとおりです。
私の環境(CentOS Linux):
- g++: 4.1.2
- アイコンv: 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;
}
私の手順:
- -finput-charset オプションについて g++ のマニュアルを読みました。 g++ のマニュアルには次のように書かれています。
-finput-charset=charset 入力ファイルの文字セットから GCC が使用するソース文字セットへの変換に使用される入力文字セットを設定します。ロケールが指定されていない場合、または GCC がロケールからこの情報を取得できない場合、デフォルトは UTF-8です。これは、ロケールまたはこのコマンド ライン オプションでオーバーライドできます。現在、競合がある場合は、コマンド ライン オプションが優先されます。charset は、システムの「iconv」ライブラリ ルーチンでサポートされている任意のエンコーディングにすることができます。
- したがって、次のようにコマンドを入力しました。
g++ -finput-charset=UTF-16BE main.cpp
これらのエラーが発生しました:
main.cpp:1 からインクルードされたファイル:
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/iostream:1: エラー: プログラムで '\342' が外れています
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/iostream:1: エラー: プログラムで '\274' が外れています
...(繰り返し、たくさん、約 4000+)...
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/iostream:1: エラー: プログラムで '\257' が外れています
main.cpp: 関数 'int main()' 内:
main.cpp:5: エラー: 'cout' は 'std' のメンバーではありません
main.cpp:5: エラー: 'endl' は 'std' のメンバーではありません</p>
- マニュアルのテキストは、文字セットが「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" がエラーなしで生成されたことに注意してください。実行すると、正しい出力が生成されました。
ついに...
どこを間違えたのかわかりませんでした。このコンパイラ オプションの例をいくつか見つけようとして Web を検索しましたが、見つかりませんでした。
お知らせ下さい!ありがとう!
さらなる編集:
みんなありがとう!あなたの返事は速いです!いくつかの更新:
- 「UTF-16」と言ったとき、「UTF-16 + BOM」を意味しました。実際、私は UTF-16BE を使用しました。上記のテキストを更新しました。
- UTF-16 以外のヘッダー ファイルが原因でエラーが発生したという回答もあります。これが事実である場合の私の考えは次のとおりです。C/C++ プロジェクトを作成するときは、常にいくつかの標準ヘッダー ファイルを含めますよね? stdio.h や iostream など。G++ コンパイラが、私たちが作成したソース ファイルのエンコーディングのみを処理し、標準ライブラリのソース ファイルを処理しない場合、この -finput-charset オプションは何のために存在するのでしょうか??
最終編集:
最後に、私の解決策は次のとおりです。
- 最初に、「Mr Lister」が以下に述べたように、ソース ファイルのエンコーディングを GB2312 に変更しました。これはしばらくの間うまくいきましたが、システムの他の部分のほとんどが通信とインターフェイスにまだ UTF-8 を使用しているため、後で自分の状況には適していないことがわかりました。そのため、多くの場所でエンコーディングを変換する必要があります...私の作業のオーバーヘッドであり、プログラムのパフォーマンスが低下する可能性もあります。
- 後で、すべてのソース ファイルを UTF-8 + BOM に変換しようとしました。このように、Windows の Visual Studio は問題なくコンパイルできますが、Linux の GCC は文句を言います。次に、BOM を削除するシェル スクリプトを作成し、GCC でコードをコンパイルする前に、まずこのスクリプトを実行します。
- 幸いなことに、プロジェクトで継続的インテグレーション ツールの TeamCity を使用してビルドを自動的に生成するため、Linux でコードを手動でビルドする必要はありません。毎日のビルドが始まる前にこのスクリプトを実行できるように、TeamCity のビルド手順を変更できます。
- この UTF-8 + BOM + スクリプト方式では、Linux でソース コードを編集しないことにしました。編集したい場合は、コードをコミットする前に、コードが正常にビルドできることを確認する必要があるためです。コードをビルドする前に BOM を削除するスクリプト。つまり、SVN はすべてのファイルが変更された (BOM が削除された) ことを報告するため、間違ったファイルを誤ってコミットするのが非常に簡単になります。この問題を解決するために、別のシェル スクリプトを作成して、BOM をソース ファイルに追加し直しました。私はまだ Linux で自分のコードを頻繁に編集するわけではありませんが、本当に必要なときは、コミット ダイアログで非常に長い変更リストに直面する必要はありません。