0

私が欲しいのは、ファイルを作成することだけですが、LinuxとWindowsでは正しく表示された名前を使用します。

Linuxでは、このコードは正常に機能しますが、UTF-8が適切に処理されているためだと思います。

Windowsではいくつかの問題があります。私は英語とロシア語の2つの言語を設定しています。プログラミング環境(QT Creator)でシステムエンコーディングを使用する場合、作成されたファイルの名前はほぼ正しくなりますが、後悔するために、ドイツ語、フランス語(日本、中国語も例外ではない)からの他の文字を名前に使用することはできませんファイルの、そうでなければ、それらが切り捨てられていることがわかるように。だから、それは悪いアプローチです。名前は任意の異なる言語からのものである可能性があるためです。

つまり、名前をそのように見せたかったのです。
string s="тдöüлотдFILE";

しかし、それはそう見えます:

ここに画像の説明を入力してください

正しく機能することを期待して、QtCreatorのエンコーディングをUTF-8に変更しました。

しかし今、私はこれを手に入れました:

string s="тдöüлотдFILE"; - expected name

名付けられた名前: ここに画像の説明を入力してください それはさらに悪く見えます。

Qt CreatorのエンコーディングをUTF-16に変更しようとしましたが(Windowsが使用していると聞きました)、その結果、コンパイラはこのエンコーディングでコードをコンパイルすることを拒否します(UTF16LE、BE、UTF32でも同じです)

全体の状況:

ここに画像の説明を入力してください

問題は、Windowsが名前を解釈する方法にあると思います。しかし、Linuxで動作すると同時に、本来あるべき姿で正しく表示されるようにするにはどうすればよいでしょうか。

4

2 に答える 2

2

まあ、これはそれを修正する方法を説明していませんが、私は500文字以上が「必要」です:-)

私が(紛らわしい方法で...)説明しようとする前に、あなたが見ている問題は何ですか:プラットフォームのファイル名を条件付けしようとするかもしれません(各プラットフォームを識別するための公式マクロを思い出せません、正しいものと交換してください):

#if defined(LINUX)
const char* Filename="тдöüлотдFILE";
#elif defined(WINDOWS)
const wchar_t* Filename=L"тдöüлотдFILE";
#endif

fstream f(Filename,...);

これでも、ソースコードがコンパイラが期待するエンコーディングである必要があります。それがシステムコードページである場合、これらの文字を文字列リテラルに変換することさえできない可能性があります(ただし、wchar_tバージョンが機能する場合は、文字の整数コードを使用してファイル名を作成することもできます。読みにくくなります。ただし、ソースファイルのエンコーディングには依存しません)。

あなたが扱っている問題は非常に複雑であり、簡単な方法で解決することは不可能かもしれません。

Windowsは内部でUTF16を使用しています(XP、2000、およびNTはUCS2を使用していたため、9xおよび3.xはコードページを使用していました)。LinuxユーザーはほとんどUTF-8に移行していますが、それについて聞いたことがない開発者もいます。しかし、それは改善しています。

現在、UTF-8にはコードページ値がありますが、実際にはシステムコードページにすることはできません。コードページの値は、コードページとUTF-16の間で変換する関数専用ですが、各システムには、UTF-8ではないレガシーコードページがあります。Windowsのレガシーまたは「ANSI」APIはシステムコードページでエンコードされた文字列を受け取りますが、UnicodeAPIはUTF-16でそれらを受け取ります。他に選択肢はありません。

したがって、明らかに、WindowsプログラムはUTF-16を使用するのが好きです。ただし、Linuxはそれをまったく好きではなく、UTF-8を好みます。私は自分のフレームワークを使用して、Windows、Linux、MacOSの間でこのような問題(そしてもちろん他のもの)を活用できるようにしています。Qtなどの既存のフレームワークもそれを行います。そのような助けがなければ、最も安全なオプションはASCIIの文字列リテラルに固執することです。

IDE設定は、ソースコードの保存方法にのみ影響します。ランタイムがリテラルを処理する方法や、ランタイムが最終的に使用するAPIに影響を与えることはできません。

「ANSI」(いいえ、なぜその名前を選んだのかわかりませ)やUnicodeを使用してプログラムをコンパイルできるようにするためのMicrosoftの「TCHAR」セットアップを使用するなど、簡単なスイッチで何かを調理してみることができます。私は特に詳しくはありませんが、文字列リテラルの型(TCHARなど)と文字列リテラルのマクロを定義し、Windows API関数の適切なマッピングを行います(「CreateFile」の呼び出しなど)。 CreateFileWまたはCreateFileAの呼び出しになります)。頭に浮かぶオプションの1つは、Windows用のUnicodeとしてコンパイルし、Linux用の適切なものをtypedef / defineして、コードの「char」ベースのバリアントを生成することです。std::stringの代わりにstd::basic_stringを使用する必要がある場合もあります。

補足として、私の知る限り、VisualC++2012はUTF-8およびUTF-16のソースコードを受け入れます。ただし、「char *」リテラルに何が含まれるかはわかりません(私のコードでは、このようなリテラルのASCIIのみを安全側に許可しています。「あいまいな」文字はとにかく文字列ファイルから取得されます。必要なのは次のリテラルのみです。ファイル名、レジストリキー、内部キーなど)。

于 2012-10-06T15:26:22.477 に答える
0

原則として、Unicode(非ASCII)文字列をansi文字列リテラルとして記述することはお勧めできません。この文字列は1バイト文字を使用するため、Unicode文字を処理できず、コンパイラはUTF-8(this UTF-8はOSのネイティブエンコーディングであるため、ほとんどのPOSIXコンパイラではデフォルトですが、C ++標準ではなくコンパイラに依存することを忘れないでください)またはシステムのデフォルトエンコーディングを使用してください(Windowsではコントロールパネルで構成できるため、コードが機能する可能性があります)あるシステムでは失敗し、別のシステムでは失敗します)。正しい方法は、C ++ワイド文字列リテラルをとして使用することですL"тдöüлотдFILE"。この場合、コンパイラは、すべての設定を持つすべてのマシンで機能する文字列のUnicode表現を出力します。

問題は、POSIXでのファイルシステムがUTF-8で動作し、WindowsでUTF-16で動作するboostことです。使用がオプションの1つである場合は、すべてのことを実行するlovelyboost::pathを使用できます。それ以外の場合は、Windowsで条件付きコンパイルを使用して実装できます。 POSIX

于 2012-10-06T15:29:06.070 に答える