代码之家  ›  专栏  ›  技术社区  ›  Angle.Bracket

如何用C++将UTF-8文件名写入MS Windows控制台?

  •  1
  • Angle.Bracket  · 技术社区  · 3 月前

    看看这段代码(在Windows 10上使用MSVC 19.42和/utf8/std:c++20选项编译)

    #include <iostream>
    #include <locale>
    #include <filesystem>
    #include <fstream>
    
    int main() {
       std::locale::global(std::locale("en_US.UTF-8"));
        
        std::filesystem::path p1(u8"ÄÖÜ.txt");
        std::ofstream(p1) << "ABC";
        std::cout << p1.filename() << "\n";
      
        std::filesystem::path p2(u8"файл.txt");
        std::ofstream(p2) << "ABC";
        std::cout << p2.filename() << "\n";
    }
    

    程序执行后,我可以在Windows控制台窗口中看到以下内容:

    D:\GitHubProjects\Cpp_Concurrency>dir D:\Temp\Folder
     Directory of D:\Temp\Folder
    
    02/16/2025  05:42 PM    <DIR>          .
    02/16/2025  05:42 PM    <DIR>          ..
    02/16/2025  05:42 PM                 3 ÄÖÜ.txt
    02/16/2025  05:42 PM                 3 файл.txt
                   2 File(s)              6 bytes
                   2 Dir(s)  884,556,988,416 bytes free
    

    但程序的输出如下:

    D:\>create_files.exe
    "ÄÖÜ.txt"
    "????.txt"
    

    关于为什么程序不能正确打印第二个文件名,有什么提示吗?

    1 回复  |  直到 3 月前
        1
  •  2
  •   Mark Tolonen    3 月前

    cmd.exe不需要UTF-8编码。通过以下方式将终端更改为UTF-8 chcp 65001 (UTF-8代码页):

    C:\test>chcp
    Active code page: 437
    
    C:\test>test
    "ÄÖÜ.txt"
    "????.txt"
    
    C:\test>dir *.txt
     Volume in drive C is Windows
     Volume Serial Number is 8E84-82D1
    
     Directory of C:\test
    
    02/16/2025  09:17 AM                 3 ÄÖÜ.txt
    02/16/2025  09:17 AM                 3 файл.txt
                   2 File(s)              6 bytes
                   0 Dir(s)  1,858,843,865,088 bytes free
    
    C:\test>chcp 65001
    Active code page: 65001
    
    C:\test>test
    "ÄÖÜ.txt"
    "файл.txt"
    
        2
  •  0
  •   int main    3 月前

    Windows控制台未默认为unicode 代码页 ,但可以从代码中更改。

    选项1:

    int main()
    {
    #ifdef _WIN32 // console UTF-8
        system("chcp 65001");
    #endif
    }
    

    选项2:

    #ifdef _WIN32
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    #include <locale.h>
    #endif // _WIN32
    
    int main()
    {
    #ifdef _WIN32 // console UTF-8
        setlocale(LC_CTYPE, ".UTF8");
        SetConsoleOutputCP(CP_UTF8);
        SetConsoleCP      (CP_UTF8);
    #endif
    }