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

新Visual Studio MFC项目中fopen_s无法工作,如何用CFile配合fgetc?

解决方案

一、修复fopen_s()无法打开文件的问题

新Visual Studio MFC项目默认使用Unicode字符集,而旧项目大概率是多字节字符集,直接传递CString(宽字符串)给fopen_s()的窄字符版本会导致参数类型不匹配,这是打开失败的核心原因。可以通过以下两种方式解决:

1. 转换宽字符串为窄字符串

使用MFC的CT2A宏将CString转换为const char*,适配fopen_s()的参数要求:

CString fname = "some known file with path";
FILE* stream;

// 转换宽字符串到窄字符串,调用fopen_s
if (fopen_s(&stream, CT2A(fname), "r") != 0) {
    // 处理文件打开失败逻辑
}

2. 直接使用窄字符串类型

如果文件路径本身是ASCII字符,也可以直接用CStringA替代CString:

CStringA fname = "some known file with path";
FILE* stream;

if (fopen_s(&stream, fname, "r") != 0) {
    // 处理文件打开失败逻辑
}

二、用CFile配合fgetc()的方案

如果需要保留CFile的使用,可通过_fdopen()将CFile的文件描述符转换为FILE*,从而调用fgetc():

CString fname = "some known file with path";
CFile file;

if (file.Open(fname, CFile::modeRead | CFile::typeBinary)) {
    // 复制文件描述符,避免关闭FILE*时影响CFile的句柄
    int dup_fd = _dup(file.m_hFile);
    FILE* stream = _fdopen(dup_fd, "rb");
    
    if (stream != nullptr) {
        int ch;
        // 使用fgetc读取字符
        while ((ch = fgetc(stream)) != EOF) {
            // 处理读取到的字符
        }
        // 关闭FILE*,不影响CFile
        fclose(stream);
    }
    
    file.Close();
}

注意:使用_dup()复制文件描述符是为了让CFile和FILE*各自管理独立的句柄,避免重复关闭导致的错误;打开模式要保持一致(比如CFile::typeBinary对应"rb")。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 12:23:24