文件路径字符编码问题导致写文件乱码或失败问题

        fopen接口默认使用ANSI解析文件路径,如果文件路径(含文件名称)不是ANSI编码的情况下,会出现写文件失败或文件名称乱码的问题。

        解决方法有两个:一个是将路径转换为ANSI(存在风险,如果路径中的字符不在ANSI字符集里转换后会乱码);一个是将路径转换为UNICODE(保险),在调用_wfopen_s接口打开文件;

备注:ANSI依赖于操作系统语言,比如中文系统ANSI就是GB2312

代码示例:

bool ANSIToWide(std::wstring& wstr, const std::string& ansi)
{
    int size = MultiByteToWideChar(CP_ACP, NULL, ansi.c_str(), ansi.size(), NULL, NULL);
    wchar_t* wide = new wchar_t[size];
    wmemset(wide, L'\0', size);
    size = MultiByteToWideChar(CP_ACP, NULL, ansi.c_str(), ansi.size(), wide, size);
    wstr.assign(wide, size);
    delete[] wide;
    wide = NULL;

    return true;
}

// 写文件
bool WriteFile(const std::string& file_path)
{
    FILE* file_handle = nullptr;
    bool ret = false;

    do 
    {
        errno_t err;

        // 如果文件路径(含文件名称)的语言不在ANSI字符编码里,会出现写文件失败或文件名称乱码的问题
        // ANSI依赖于操作系统语言,比如中文系统ANSI就是GB2312
        //err = fopen_s(&file_handle, file_path.c_str(), "a");

        wstring wstr;
        ANSIToWide(wstr, file_path);    // UTF-8编码转宽字节(UTF-16)
        err = _wfopen_s(&file_handle, wstr.c_str(), L"a");

        if (0 != err)
        {
            std::cout << "Open file failed, err: " << err << " file path: " << file_path.c_str() << std::endl;
            break;
        }

        std::string data = "test";
        size_t size = fwrite(data.c_str(), 1, data.size(), file_handle);
        if (size != data.size())
        {
            std::cout << "Write data to file failed, err: " << err << " data: " << data.c_str() << std::endl;
            break;
        }

        ret = true;
        std::cout << "Write data to file success, data: " << data.c_str() << std::endl;
    } while (false);

    if (nullptr != file_handle)
    {
        fclose(file_handle);
        file_handle = nullptr;
    }

    return ret;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值