MFC中利用CFileDialog选择文件并读取文件所遇到的问题和解决方法
在用MFC编写一个上位机时,需要实现选择和读取一个二进制文件,本来以为很简单的但是在实现过程中遇到很多问题,所幸都一一解决,这里做一下记录。
首先在实现文件选择,在界面上设置一个按钮,并在点击事件函数中输入以下:
1 void CWeatherStationDlg::OnBnClickedButton6()//选择文件 2 { 3 // TODO: 在此添加控件通知处理程序代码 4 m_strHistoryPath = "";//文件选择清空 5 CFileDialog dlg(TRUE,_T("txt"),NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,_T("文本文件|*.txt||")); 6 if (dlg.DoModal()==IDOK) 7 { 8 m_strHistoryPath = dlg.GetPathName(); 9 if (m_strHistoryPath == "") 10 { 11 MessageBox(_T("未选择文件!")); 12 return; 13 } 14 } 15 ((CEdit*)GetDlgItem(IDC_EDIT5))->SetWindowText(m_strHistoryPath); 16 17 }
然后实现了文件选择,此时文件路径保存在 CString m_strHistoryPath中。然后需要打开改文件,这里采用了fopen打开,需要将CString 格式转为char *格式,先采用强制类型转换:
FILE *fReadHistory = NULL; char *cReadHis; cReadHis=(char*)malloc(200*sizeof(char)); cReadHis= (LPSTR)(LPCTSTR)m_strHistoryPath; fReadHistory = fopen(cReadHis, "rb"); fread(strStarLine,1,1,fReadHistory);
此时fread中始终没有数据读入,后来经过查找了解由于当前编译环境为 Unicode,CString 实际上是 CSringW,虽然强转成了 const char *,但你实际发出去的字符串是 "A\0B\0C\0"六个字节。
后来又采用了WideCharToMultiByte();
1 FILE *fReadHistory = NULL; 2 char *cReadHis; 3 cReadHis=(char*)malloc(200*sizeof(char)); 4 memset(cReadHis,0,sizeof(cReadHis)); 5 int n = m_strHistoryPath.GetLength(); //获取宽字节字符的大小,大小是按字节计算的 6 int len = WideCharToMultiByte(CP_ACP,0,m_strHistoryPath,m_strHistoryPath.GetLength(),NULL,0,NULL,NULL); 7 WideCharToMultiByte(CP_ACP,0,m_strHistoryPath,m_strHistoryPath.GetLength(),cReadHis,len,NULL,NULL); 8 cReadHis[len+1]='/0'; //多字节字符以'/0'结束 9 10 fReadHistory = fopen(cReadHis, "rb");
但是此时cReadHis后面存在乱码,导致文件无法打开。
又经过查找文件了解
WideCharToMultiByte(CP_ACP,0,m_strHistoryPath,m_strHistoryPath.GetLength(),cReadHis,len,NULL,NULL);
应改为
WideCharToMultiByte(CP_ACP,0,m_strHistoryPath,m_strHistoryPath.GetLength()+1,cReadHis,len+1,NULL,NULL);
此时路径就正常了,文件也能正常读入。原因暂时还未深究。
此时再补充一点,在程序编写时输入文件读取地址一定不能用单斜杆“\”,需要改为反向单斜杆“/”或双斜杠“\\”,但是用文件选择CFileDialog 读入路径时是不受影响的,内部已经进行过转义。我在这里纠结过很长时间,发现其实不是这里的问题。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程