You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++11跨Windows/Linux创建Unicode文件名文件的问题求助

Cross-platform C++11 Code to Create Files with Unicode Filenames (Windows/Linux)

Let's break down why your previous attempts failed and fix the core issue first—then we'll build a working cross-platform solution that fits your constraints.

The Root Problem: Windows Terminal Encoding Mismatch

Linux terminals default to UTF-8, so your input äöüé.txt is directly stored as UTF-8 bytes in std::string, which the Linux kernel understands perfectly.

On Windows, however, your terminal uses an OEM code page (yours is CP850). The äöüé characters you type are stored as CP850-encoded bytes, not UTF-8. Your earlier code tried to convert these bytes as if they were UTF-8, which is why you got garbled filenames like „”‚.txt.


Working Cross-Platform Solution

This code uses only C11 standard libraries and Windows API functions (where needed), no C17 filesystem or third-party libraries.

Complete Code

#include <iostream>
#include <fstream>
#include <string>
#include <cstdio> // For _wfopen, fclose

#ifdef _MSC_VER
#include <windows.h>

// Convert OEM-encoded string (from Windows terminal) to UTF-16 (wstring)
std::wstring OemToUtf16(const std::string& oem_str) {
    int wide_length = MultiByteToWideChar(CP_OEMCP, 0, oem_str.c_str(), static_cast<int>(oem_str.size()), nullptr, 0);
    if (wide_length == 0) {
        return {};
    }
    std::wstring wide_str(wide_length, L'\0');
    MultiByteToWideChar(CP_OEMCP, 0, oem_str.c_str(), static_cast<int>(oem_str.size()), &wide_str[0], wide_length);
    return wide_str;
}
#endif

int main() {
    std::string fileName;
    std::cout << "Please enter the name of file ! " << std::endl;
    std::cin >> fileName;
    std::cout << "name = " << fileName << std::endl;

    bool fileCreated = false;

#ifdef _MSC_VER
    // Convert terminal input (OEM) to UTF-16 for Windows API
    std::wstring wideFileName = OemToUtf16(fileName);
    if (!wideFileName.empty()) {
        // Use _wfopen to create file with Unicode filename
        FILE* fileHandle = _wfopen(wideFileName.c_str(), L"wb");
        if (fileHandle != nullptr) {
            // Associate with std::ofstream if you want to use standard streams
            std::ofstream outputStream(fileHandle);
            outputStream << "Hello Unicode Filename!\n";
            outputStream.close(); // Closes both stream and FILE*
            fileCreated = true;
        }
    }
#else
    // Linux: Directly use UTF-8 string with std::fstream
    std::ofstream outputStream(fileName, std::ios::out | std::ios::trunc | std::ios::binary);
    if (outputStream.is_open()) {
        outputStream << "Hello Unicode Filename!\n";
        outputStream.close();
        fileCreated = true;
    }
#endif

    if (fileCreated) {
        std::cout << "File created successfully!" << std::endl;
    } else {
        std::cout << "Failed to create file!" << std::endl;
    }

    return 0;
}

Fixes for Your Previous Attempts

Let's clarify why your earlier approaches didn't work:

  1. Method 1: You used MultiByteToWideChar(CP_UTF8, ...)—but Windows terminal input isn't UTF-8, it's OEM. Switching to CP_OEMCP fixes the conversion.
  2. Method 2: CreateFileA uses the system's ANSI code page (e.g., CP1252), not the terminal's OEM code page. Using CreateFileW with UTF-16 would work, but _wfopen is simpler for integrating with standard streams.
  3. Method 3: Your codecvt setup didn't account for the OEM-to-UTF16 conversion, so the input string's encoding was invalid for Windows API calls.

Additional Windows Testing Tip

If you want to read filenames directly with std::wcin, set the correct locale first to handle OEM input properly. Add this to the start of main() on Windows:

setlocale(LC_ALL, ".OCP"); // Set locale to match terminal's OEM code page
std::wstring wideFileName;
std::wcout << L"Please enter the name of file ! " << std::endl;
std::wcin >> wideFileName;
// Use _wfopen(wideFileName.c_str(), L"wb") directly

内容的提问来源于stack exchange,提问作者Franck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 09:22:52