6

私たちのコードは以前はファイル名に日本語の文字を含むファイルを書き込んでいたが、すべての場合に機能しなくなったとお客様から苦情が寄せられています。ファイル名を表すために古き良き char * 文字列を常に使用していたので、それが機能したことに少しショックを受けました。私たちのソフトウェアからエクスポートされたファイル名が埋め込まれたファイルを送ってもらいました。文字列は、日本語の文字を表すために 2 バイト シーケンスの最初の文字として 16 進数の文字 82 と 83 を使用しているようです。オンラインで調べてみると、これはおそらく SHIFT_JIS および/または Windows コードページ 932 であると思われます。

何が起こっているかは、以前は fopen と ofstream::open の両方で、このコードページを使用して受け入れられたファイル名のように見えます。今では fopen だけが行います。Visual Studio の fopen のドキュメントを確認しましたが、fopen に渡す文字列として許容されるものについてのヒントはありません。

短期的には、誰かが特定の Windows fopen と ofstream::open の問題に光を当ててくれることを願っています。長期的には、C++、Windows、Linux、および OS X で Unicode (およびその他の?) ファイル名を開くための受け入れられている方法を知りたいと思っています。

追加するために編集: 機能するオープンは「C」ロケールで行われるのに対し、機能しないオープンは顧客のデフォルトのロケールが何であれ行われると思います。しかし、それは何年も前からのケースであり、プログラムの古いバージョンは現在でも彼らのシステムで動作しているため、これは私たちが目にしている問題を説明するためのロングショットのようです.

更新: お客様に小さなテスト プログラムを送信しました。fopen が SHIFT_JIS ファイル名で正常に動作することを確認しましたが、std::ofstream は動作しません。これは Visual Studio 2005 で発生し、既定のロケールを使用したか "C" ロケールを使用したかに関係なく発生しました。

誰かがこの動作の説明を持っているかどうか (そして、なぜそれが不思議に変わったのか - おそらく VS2005 のサービス パック?) を知り、移植可能な C++ コードで Unicode ファイル名を処理するための包括的な「ベスト プラクティス」をまとめたいと思っています。

4

6 に答える 6

3

fopen や ofstream::open などの関数は、ファイル名を char * として受け取りますが、これはシステム コード ページにあるものとして解釈されます。

これは、Shift-JIS (cp932)、または簡体字中国語 (ビッグ 5/cp936)、韓国語、アラビア語、ロシア語などで表される日本語の文字を使用できることを意味します (OS システム コード ページと一致する限り)。

また、日本語のシステムでのみ日本語のファイル名を使用できることも意味します。システム コード ページを変更すると、アプリケーションが「動作を停止する」 これがここで起こっていることだと思います (この領域では Windows 2000 以降、大きな変更はありません)。

これは、システム コード ページを変更する方法です: http://www.mihai-nita.net/article.php?artID=20050611a

長期的には、Unicode への移行 (および _wfopen、wofstream の使用) を検討するかもしれません。

于 2009-02-09T09:36:34.087 に答える
2

デフォルトのシステム ライブラリを使用して Unicode ファイルを使用する移植可能な方法を知りません。ただし、移植可能な機能を提供するフレームワークがいくつかあります。次に例を示します。

  • C の場合: glibは UTF-8 のファイル名を使用します。
  • C++ の場合: glibmmも UTF-8 のファイル名を使用し、glib が必要です。
  • C++ の場合: boostはファイル名に wstring を使用できます。

.NET/mono フレームワークにも移植可能なファイルシステム関数が含まれていることは確かですが、それらについては知りません。

于 2009-02-03T08:42:56.983 に答える
1

誰かまだこれ見てる?この質問を調査したところ、どこにも答えが見つからなかったので、ここで調査結果を説明しようとします。

VS2005 では、fstream ファイル名の処理は奇妙です。GetACP で取得し、[コントロール パネル]/[地域] および [言語]/[管理] で設定するシステムの既定のエンコーディングは使用しません。しかし、常に CP 1252 -- 私は信じています。

これは大きな混乱を引き起こす可能性があり、Microsoft は後の VS バージョンでこの癖を取り除きました。

VS2005 のすべての回避策には欠点があります。

  1. コードを変換してどこでも Unicode を使用する

  2. ナロー文字のファイル名を使用して fstream を開かないでください。常にシステムのデフォルト エンコーディングを使用して Unicode に変換してください。ワイド文字のファイル名 open/ctor を使用してください。

  3. GetACP() を使用してコードページを取得し、

一致する setlocale:

setlocale (LC_ALL, ("." + lexical_cast<string> (GetACP())).c_str())
于 2013-08-09T19:41:52.107 に答える
0

スレッド ロケールをシステムのデフォルト ロケールに設定する必要がある場合があります。問題の考えられる理由については、http: //connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100887を参照してください。

于 2009-01-26T19:37:52.740 に答える
0

Mac OS X は、ネイティブの文字エンコーディングとして Unicode を使用します。基本的な文字列オブジェクトは CFString と NSString です。文字の配列を Unicode として格納します。

于 2009-02-05T10:30:16.747 に答える
0

Linux では、ファイル名文字列が UTF-8 文字列 (たとえば、EXT3 ファイルシステムでは、許可されていない文字はスラッシュと NULL のみ) であり、通常のchar *. manページには文字エンコーディングについて言及されていないようです。これが、UTF-8のシステム標準であると私に信じさせるものです。OS X は同様のルーツに由来するため、おそらく同じものを使用しますが、これについてはよくわかりません。

于 2009-01-26T18:41:53.600 に答える