新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
相关产品推荐
相关产品推荐

