6

Linux で例外をスローしている C++ コードのサンプルがあります。

namespace fs = std::filesystem;
const fs::path pathDir(L"/var/media");
const fs::path pathMedia = pathDir / L"COMPACTO - Diogo Poças.mxf" // <-- Exception thrown here

スローされる例外は次のとおりです。filesystem error: Cannot convert character sequence: Invalid in or incomplete multibyte or wide character

問題はçキャラクターの使用に関連していると推測します。

  1. このワイド文字列 (wchar_t) が「無効または不完全なマルチバイト文字またはワイド文字」なのはなぜですか?
  2. 今後、関連するコードをクロスプラットフォームにして、Windows や Linux で実行するにはどうすればよいでしょうか。
    • 使用する必要があるヘルパー関数はありますか?
    • プログラマーの PoV から強制する必要のあるルールは何ですか?
    • ここで「Linux ではワイド文字列を使用しないでください」という回答を見ましたが、Windows でも同じ規則を使用しますか?

Linux 環境 (クロスプラットフォームで実行したいという事実を忘れないでください):

  • Ubuntu 18.04.3
  • gcc 9.2.1
  • C++17
4

2 に答える 2

3

残念ながらstd::filesystem、少なくとも宣伝されているほどではなく、オペレーティング システムの互換性を念頭に置いて作成されたものではありません。

Unix ベースのシステムの場合、UTF8 ( u8"string"、または単に"string"コンパイラによって異なります) が必要です。

Windows の場合、UTF16 ( L"string")が必要です。

C++17では使用できますfilesystem::u8path(何らかの理由でC++20では非推奨です)。Windows では、これにより UTF8 が UTF16 に変換されます。UTF16 を API に渡すことができるようになりました。

#ifdef _WINDOWS_PLATFORM
    //windows I/O setup
    _setmode(_fileno(stdin), _O_WTEXT);
    _setmode(_fileno(stdout), _O_WTEXT);
#endif

fs::path path = fs::u8path(u8"ελληνικά.txt");

#ifdef _WINDOWS_PLATFORM
    std::wcout << "UTF16: " << path << std::endl;
#else
    std::cout <<  "UTF8:  " << path << std::endl;
#endif

または、独自のマクロを使用して、Windows の場合は UTF16 を設定し ( L"string")、Unix ベースのシステムの場合は UTF8 を設定します (u8"string"または単に"string")。UNICODEが Windows 用に定義されていることを確認してください。

#ifdef _WINDOWS_PLATFORM
#define _TEXT(quote) L##quote
#define _tcout std::wcout
#else
#define _TEXT(quote) u8##quote
#define _tcout std::cout
#endif

fs::path path(_TEXT("ελληνικά.txt"));
_tcout << path << std::endl;

https://en.cppreference.com/w/cpp/filesystem/path/nativeも参照してください


Visual Studio には、std::fstreamUTF16 ファイル名を使用できる特別なコンストラクターがあり、UTF8 読み取り/書き込みと互換性があることに注意してください。たとえば、次のコードは Visual Studio で機能します。

fs::path utf16 = fs::u8path(u8"UTF8 filename ελληνικά.txt");
std::ofstream fout(utf16);
fout << u8"UTF8 content ελληνικά";

Windows で実行されている最新の gcc バージョンでサポートされているかどうかはわかりません。

于 2019-10-24T16:49:43.557 に答える