当前位置:C++技术网 > 资讯 > 学习心得之六,MFC编程中两种文件对话框的浅出

学习心得之六,MFC编程中两种文件对话框的浅出

更新时间:2015-09-09 23:10:04浏览次数:1+次

    昨天我们写了篇关于如何两种文件对话框的创建文章,来实现我们自己写入的文件的读取,今天,我们更深入讲解文件的机制,以及读取出来电脑上已有的文件。若下面的代码有不懂的,请看《学习心得之五,MFC编程中两种文件对话框的创建》。

    好了,我们先把昨天的读取我们自己写入的文件的代码,先提上来:

    

void CFile1View::OnRead() 
{
 // TODO: Add your command handler code here
 CFileDialog filedlg(TRUE);
 filedlg.m_ofn.lpstrTitle="我的打开文件";
 filedlg.m_ofn.lpstrFilter="Text File(*.txt)\0*.txt\0All Files(*.*)\0*.*\0\0";
 
 if(IDOK==filedlg.DoModal())
 {
  CFile file(filedlg.GetFileName(),CFile::modeRead);
  char pBuf[100];
  DWORD dwfilelen;
  dwfilelen=file.GetLength();
  pBuf[dwfilelen]=0;
  file.Read(pBuf,dwfilelen);
  MessageBox(pBuf);
  file.Close();
 }
}


    if语句之内的代码就是来实现我们的读取操作,好吧,插一句,IDOK就是“确定”按钮的ID号,如果熟悉MFC的人,就会知道通常按钮的ID号是带有下划线的,而“确定”按钮的ID号却有点不同,我们注意下。我们定义了一个数组pBuf来接受我们之前写入的文件,最后以Message的形式显示出来。

    

DWORD dwfilelen;
dwfilelen=file.GetLength();
pBuf[dwfilelen]=0;
首先我们定义了一个表示32位长度的类型DWORD的对象dwfilelen,然后我们用它来接收我们写入文件的长度。最后我们在文件的末尾加上了0,这是为什么呢?我们知道,字符串是以'\0‘结尾,程序读取是也是遇到它结尾。如果没有找到结束标记,就会一直读下去,再读取了我们自己写入的字符后,其他的就会乱码,读取一些乱七八糟的东西。那好,我们修改下码:
void CFileView::OnFileRead() 
{
	// TODO: Add your command handler code here

	CFileDialog fileDlg(TRUE);//打开对话框
	fileDlg.m_ofn.lpstrTitle="我的打开文件对话框";
	fileDlg.m_ofn.lpstrFilter="Text File(*.txt)\0*.txt\0ALL Files(*.*)\0*.*\0\0";
	
	if(IDOK==fileDlg.DoModal())
	{
		CFile file(fileDlg.GetFileName(),CFile::modeRead);
		char pBuf[100];
		file.Read(pBuf,100);
		MessageBox(pBuf);
		file.Close();
	}
}


可以看到,我们修改了read函数,将读取长度改为了100,我们来看一下实现结果:

 

因此我们需要知道我们写入的文件的字符长度,好了,然后在最后加一个结束标记'\0',使得程序只读取我们写入的文件字符

,这个问题解决了,接下来就是我们如何来读取电脑上的文件,而不仅仅是我们自己写入的文件。可是,我们事先不知道电脑中某个文件的大小,如何读取?就像现在,我们定义了长度为100的字符数组,我们能读取电脑上的文件吗?我们来试试读取电脑上的read.txt文件:

    

    这就是我们要读的,来看看效果:

    

   这是我们以文章的第一段代码(第一个灰色区域)来读取的,如果以第三段代码(第三个灰色区域)的代码来读取,会出现差不多的结果。出现这个效果的原因就是因为我们定义的读取的数组大小不够,你可能会说那就定义一亿或者更大,可是,我们定义的数组大小是有限制的,有可能会发生数组越界,怎么办呢?来我们看解决方案,不过先讲解下,字符数字的定义问题

,我们常用的就是直接定义数组名,并分配数组大小,对不?这种定义方法最常见,因为我们接触的程序都是小程序,对数组的要求不大,但现在不行了,因此我们就得换个方法,看代码咯:

   

if(IDOK==fileDlg.DoModal())
 {
  CFile file(fileDlg.GetFileName(),CFile::modeRead);
  char *pBuf;
  DWORD dwfilelen;
  dwfilelen=file.GetLength();
  pBuf=new char[dwfilelen+1];//////////////////修改的代码
  pBuf[dwfilelen]=0;
  file.Read(pBuf,dwfilelen);
  MessageBox(pBuf);
  file.Close();
 }        


      

将这段代码与第一段代码比较,现在你就有疑问了,为什么定义数组指针了,又不分配大小?还有指针能这么复制吗?new char 又是什么东西?别急,我会解释。

    我们看下实现:

    

    

    我们可以看到,成功读取了read.txt的文件,连屏幕都放不下,之前我们定义的100个单位的内存够吗?

    

char buf[100] 与 char buf = new char [100];


是等价的,当定义全局变量时,应用程序是在堆上分配内存,而关键字new也是从堆上分配内存,两者是等价的,只不过程序运行到最后时,内存的销毁不同,我就不再解释了。这句代码都是分配100个单位的内存。可是用new char[...]来分配内存有个最大的好处,当我们需要动态分配内存时,也就是临时的根据应用程序的要求来分配内存,就用它来实现,就像我们现在遇到的问题,我们用它就能解决问题哦!关于内存的细节,大家可以下载这两本书《数据结构C++描述》《windows核心编程》本站均有链接。

    下篇可能就是介绍文本文件与二进制文件了,与这两篇文章有关。