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 读入路径时是不受影响的,内部已经进行过转义。我在这里纠结过很长时间,发现其实不是这里的问题。

posted @   艾绒  阅读(2372)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· 基于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保姆级教程
点击右上角即可分享
微信分享提示