2012-05-12 18 views
3

C++プロジェクトでは、ファイル(fstream::open())大きな問題です)。私のプログラムのWindowsビルドは悲惨に失敗します。fstream :: open()Windows上でUnicodeまたは非Ascii文字が動作しない(std :: ios :: out付き)

  • ファイル "A"(UTF-8 0xC3 0xA4の)

    std::string s = ...; 
    //Convert s 
    std::fstream f; 
    f.open(s.c_str(), std::ios::binary | std::ios::in); //Works (f.is_open() == true) 
    f.close(); 
    f.open(s.c_str(), std::ios::binary | std::ios::in | std::ios::out); //Doesn't work 
    

    ストリングsは、UTF-8でエンコードされ、その後のLatin1(0xE4)をUTF-8から変換されました。私はQtを使用していますので、QString::fromUtf8(s.c_str()).toLocal8Bit().constData()です。

    ファイルを読み込み用に開くことができますが、書き込み用に開くことができないのはなぜですか?

  • ファイル "и"(UTF-8 0xD0 0xB8)

    同じコード、全く動作しません。

この文字は、Windows-1252文字セットには入りません。どのように私はそのようなfstreamを開くことができます(私はMSVCを使用していないので、no fstream::open(const wchar_t*, ios_base::openmode))?

+1

私は、Windowsのファイル名がUTF-16でエンコードする必要があると思うし、あなたは特別なWindowsのファイルを使用する必要があります( '_wfopen'など)を使用して、長い名前でファイルにアクセスします。また、短い名前を使用することもできます。 –

+2

あなたはどのコンパイラとCライブラリを使用していますか?例えば、MinGWを使用している場合でも、['_wfopen'](http://msdn.microsoft.com/en-us/library/yeby3zcb%28v=vs.80)などのMS CRTの機能を使用できます%29.aspx)。別のCランタイム(Cygwin GCCのlibcなど)を使用している場合は、そのランタイムライブラリのUnicodeサポートが必要です。 –

+0

あなたのCおよびC++標準ライブラリはUnicodeをサポートする必要があります(つまり、UTF-8入力文字列をUTF-16に変換してから、 'CreateFileW'を呼び出す必要があります)。もしそうでなければ、あなたは運が悪いです。おそらく 'CreateFileW'を直接呼び出す必要があります。 – Philipp

答えて

3

Windows上で標準API(std :: fstreamなど)を使用すると、現在設定されている「ANSIコードページ」(CP_ACP)を使用してファイル名をエンコードできる場合にのみファイルを開くことができます。

これは、WindowsでこれらのAPIを使用して単純に開くことができないファイルが存在する可能性があることを意味します。 MicrosoftがCP_ACPをCP_UTF8に設定するサポートを実装していない限り、これはMicrosoftのCRTまたはC++標準ライブラリ実装を使用することはできません。

(Windowsには、有効にすると、ドライブ上のすべてのファイルが標準APIで使用できるASCIIファイル名を持つ「短い」ファイル名という機能がありましたが、この機能は使用できなくなっていますソリューション)。

3

STLのMicrosoftの実装では、UTF-16でエンコードされた文字列のUnicodeサポートを可能にする非標準の拡張(オーバーロード)があります。

UTF-16でエンコードされたstd :: wstringをfstream :: open()に渡すだけです。これはfstreamで動作させる唯一の方法です。

あなたは、私がここにWindows上でUnicodeをサポートするための最も簡単な方法であることを見つけるものに多くを読むことができます:http://utf8everywhere.org/

+0

これはおそらく適切な解決策ですが、AFAIKこのオーバーロードはMinGWではなくMSVCでのみ利用できます(「呼び出す機能がありません」)。私は現在MicrosoftのC++に取り組んでいるコードを移植していないので、Microsoftのコンパイラは使用しません。つまり、コードはコンパイルされず、理由もわかりません。 – basic6

+1

@ basic6:[conversion funciotns](http://utf8everywhere.org/#how.cvt)セクションをお読みください。近所の図書館もMinGWで動くはずです。 – ybungalobill

関連する問題