MFC - 文件操作 (孙鑫C++第十二讲笔记整理)

1.常量指针与指针常量的区分

 char ch[5]="lisi";

 const char *pStr=ch;//const在*之前,表明指针指向的内容为常量,即为常量指针

 char * const pStr=ch;//const在*之后,表明指针的地址不能改变,即为指针常量

 明白?

 

2.对文件读写的三种方法

 1.C中

   FILE *pFile=fopen("1.txt","w");

fwrite("http://www.sunxin.org",1,strlen("http://www.sunxin.org"),pFile);

//fseek(pFile,0,SEEK_SET);

//fwrite("ftp:",1,strlen("ftp:"),pFile);

//fwrite("http://www.sunxin.org",1,strlen("http://www.sunxin.org"),pFile);

fclose(pFile);*/

//fflush(pFile);

 

 2.C++中

/* ofstream ofs("4.txt");

ofs.write("http://www.sunxin.org",strlen("http://www.sunxin.org"));

ofs.close();*/

        要包括头文件 "fstream.h"

 

 3.MFC中用CFile类,哈哈!简单好用

CFileDialog fileDlg(FALSE);

fileDlg.m_ofn.lpstrTitle="我的文件保存对话框";

fileDlg.m_ofn.lpstrFilter="Text Files(*.txt)\0*.txt\0All Files(*.*)\0*.*\0\0";

fileDlg.m_ofn.lpstrDefExt="txt";

if(IDOK==fileDlg.DoModal())

{

 CFile file(fileDlg.GetFileName(),CFile::modeCreate | CFile::modeWrite);

 file.Write("http://www.sunxin.org",strlen("http://www.sunxin.org"));

 file.Close();

}

  4.利用win32 API函数 CreateFile(),及WriteFile()

 

4.注册表读写

 1.对win.ini的读写

//::WriteProfileString("http://www.sunxin.org","admin","zhangsan");

/* CString str;


::GetProfileString("http://www.sunxin.org","admin","lisi",

 str.GetBuffer(100),100);

AfxMessageBox(str);*/

 2.注册表的读写

HKEY hKey;

DWORD dwAge=30;

RegCreateKey(HKEY_LOCAL_MACHINE,"Software\\http://www.sunxin.org\\admin",&hKey);

RegSetValue(hKey,NULL,REG_SZ,"zhangsan",strlen("zhangsan"));

RegSetValueEx(hKey,"age",0,REG_DWORD,(CONST BYTE*)&dwAge,4);

RegCloseKey(hKey);以上是写入

 

C语言的文件操作:在菜单中定义两个文件操作的菜单选项

[cpp]  view plain copy
  1. void CFileTestView::OnXieru()   
  2. {  
  3.     // TODO: Add your command handler code here  
  4.     FILE *file;  
  5.     file=fopen("demo1.txt","w");  
  6.     fwrite("hello,this is demo",1,strlen("hello,this is demo"),file);  
  7.     fclose(file);//因为C语言的文件操作是通过缓冲区来完成的,如果没有这句的话,  
  8.     //运行程序之后,如果没有关闭程序,则demo1.txt的内容读取不了  
  9.       
  10.     //也可以使用如下代码解决问题,以时刻更新文件  
  11.     //fflush(file);  
  12.       
  13.       
  14. }  
  15.   
  16. void CFileTestView::OnDuqu()   
  17. {  
  18.     // TODO: Add your command handler code here  
  19.     FILE *file;  
  20.     file=fopen("demo1.txt","r");  
  21.     char ch[100];//定义一个字符数组来保存读取的值  
  22.     fread(ch,1,100,file);//使用读取文件的函数,  
  23.     MessageBox(ch);//输出读取的文件,因为文件并没有100个字符,所以后面会有乱码  
  24.   
  25.       
  26. }  

解决上面出现乱码的几个方法

1在写入文件的时候,strlen("XXX")+1,则最后写入的字符是'\0'刚好是用于判断字符串结束的标志

2不用改变写操作,直接:

[cpp]  view plain copy
  1. FILE *file;  
  2. file=fopen("demo1.txt","r");  
  3. char ch[100];  
  4. memset(ch,0,100);//把数组都初始化为0,当读取到0的时候,字符串结束符,你懂的  
  5. fread(ch,1,100,file);  
  6. MessageBox(ch);  


3使用C函数fseek和ftell的配合

[cpp]  view plain copy
  1. FILE *file;  
  2.     char *ch;//这里暂时不知道大小,所以后面动态分配内存,char ch[len]+1;这是错误的,数组定义的时候不能有变量  
  3.     file=fopen("demo1.txt","r");  
  4.     fseek(file,0,SEEK_END);  
  5.     int len=ftell(file);  
  6.     ch=new char[len+1];//分配多一个字节,用以存文件结束符  
  7.     fseek(file,0,SEEK_SET);//读取文件之前,这里记得把指针位置调回到开始位置,也可以使用rewind(file)函数  
  8.     fread(ch,1,len,file);  
  9.     ch[len]=0;  
  10.     MessageBox(ch);  


写入文件的时候:

[cpp]  view plain copy
  1. FILE *file;  
  2. file=fopen("demo2.txt","w");  
  3. char ch[3];  
  4. ch[0]='a';  
  5. ch[1]=10;//表示换行的ASCII码  
  6. ch[2]='b';  
  7. fwrite(ch,1,3,file);  
  8. fclose(file);  

这个时候看到的文件属性显示的是4个字节而不是3个字节,这是因为默认的fopen类型是文本类型,换行前面自动加了一个字节的回车

读取文件的时候:

[cpp]  view plain copy
  1.         FILE *file;  
  2. file=fopen("demo2.txt","r");  
  3. char ch[100];  
  4. fread(ch,1,3,file);  
  5. ch[3]=0;  
  6. MessageBox(ch);  
  7. fclose(file);  

写入文件用了4个字节,读取文件用3个字节,却能正常显示,这是因为文本读取方式,遇到换行和回车的ASCII码的时候,自动组合成了换行

假设,写入方式跟上面一样,用文本方式写入

而读取方式使用二进制读取

[cpp]  view plain copy
  1. FILE *file;  
  2. file=fopen("demo2.txt","rb");  
  3. char ch[100];  
  4. fread(ch,1,3,file);  
  5. ch[3]=0;  
  6. MessageBox(ch);  
  7. fclose(file);  


则读取是一个a,为什么呢,因为写进去了4个字符,而读取的是3个字符。

 

写入和读取都是二进制形式的话,都能正常读取,写入的是3个字节



 

所以写入和读取的方式要一致,同为文本或同为二进制

二进制文件不要用文本方式去读取,统一按照二进制去读取,是不会出错的。

不管是二进制文件还是文本文件,都可以使用二进制方式去打开,进行写入和读取。

对二进制,如果以文本方式去打开和写入,就可能会出现问题。

 

往文件输入数字:

[cpp]  view plain copy
  1. FILE *file;  
  2.     file=fopen("demo4.txt","w");  
  3.     char *p="98341";  
  4.     fwrite(p,1,5,file);  
  5.     fclose(file);  

直接int =98341;fwrite(&i,4,1,file);这样只会输出乱码。

下面的方法是等价的

[cpp]  view plain copy
  1. FILE *file;  
  2.     file=fopen("demo5.txt","w");  
  3.     char ch[5];  
  4.     ch[0]='9';  
  5.     ch[1]='8';  
  6.     ch[2]='3';  
  7.     ch[3]=48+4;  
  8.     ch[4]='0'+1;  
  9.     fwrite(ch,1,5,file);  
  10.     fclose(file);  

下面是C++方法文件操作:

[cpp]  view plain copy
  1. ofstream xieru("demo6.txt");  
  2.     xieru.write("hello,use c++ iostream",strlen("hello,use c++ iostream"));  
  3.     xieru.close();  


 

[cpp]  view plain copy
  1. ifstream xianshi("demo6.txt");  
  2.     char ch[100];  
  3.     memset(ch,0,100);  
  4.     xianshi.read(ch,100);  
  5.     MessageBox(ch);  
  6.     xianshi.close();  


也可以这样:

[cpp]  view plain copy
  1. ofstream xieru("demo7.txt");  
  2. xieru<<"hello,use c++ iostream"<<endl;  
  3. xieru.close();  


 

[cpp]  view plain copy
  1. ifstream xianshi("demo7.txt");  
  2. char c;  
  3. CString cstring="";  
  4. while(xianshi>>c)  
  5.     cstring+=c;  
  6. MessageBox(cstring);  


异曲同工之妙,下面是分别是WIN API 和MFC的文件操作展示

API:

[cpp]  view plain copy
  1. HANDLE handle=CreateFile("demo9.txt",GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);  
  2.       
  3.     DWORD count;  
  4.     WriteFile(handle,"use c++ to show the io oper",strlen("use c++ to show the io oper"),&count,NULL);  
  5.       
  6.     CloseHandle(handle);  


 

[cpp]  view plain copy
  1. HANDLE handle;  
  2.     handle=CreateFile("demo9.txt",GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);  
  3.   
  4.     char ch[100];  
  5.     memset(ch,0,100);  
  6.     DWORD geshu;  
  7.     ReadFile(handle,&ch,100,&geshu,NULL);  
  8.     MessageBox(ch);  
  9.     CloseHandle(handle);  


或者:

[cpp]  view plain copy
  1. HANDLE handle;  
  2.     handle=CreateFile("demo9.txt",GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);  
  3.       
  4.     char ch[100];  
  5.     DWORD geshu;  
  6.     ReadFile(handle,ch,100,&geshu,NULL);  
  7.     ch[geshu]=0;  
  8.     MessageBox(ch);  
  9.     CloseHandle(handle);  


MFC:

[cpp]  view plain copy
  1. CFile cf;  
  2.     cf.Open("demo10.txt",CFile::modeWrite|CFile::modeCreate);  
  3.     cf.Write("hello,use MFC to show",strlen("hello,use MFC to show"));  
  4.     cf.Close();  


或:

[cpp]  view plain copy
  1. CFile cf("demo10.txt",CFile::modeWrite|CFile::modeCreate);  
  2. cf.Write("hello,use MFC to show",strlen("hello,use MFC to show"));  
  3. cf.Close();  


读取:

[cpp]  view plain copy
  1. CFile cf("demo10.txt",CFile::modeRead);  
  2.       
  3.     int len=cf.GetLength();  
  4.     char *ch=new char[len+1];  
  5.     cf.Read(ch,len);  
  6.     ch[len]=0;  
  7.     MessageBox(ch);cf.close();  

MFC的文件操作简单很多,真的。

[cpp]  view plain copy
  1. CFileDialog cfileDlg(false);//文件对话框  
  2.     cfileDlg.m_ofn.lpstrDefExt="txt";  
  3.     cfileDlg.m_ofn.lpstrTitle="我的文件保存对话框";  
  4.     cfileDlg.m_ofn.lpstrFilter="Text File(*.txt)\0*.txt\0All File(*.*)\0*.*\0\0";  
  5.     //设置过滤器,是一对一对的值,每个字符串后面有个\0,结束的时候需要两个\0  
  6.   
  7.     if(IDOK==cfileDlg.DoModal())  
  8.     {  
  9.         CFile cfile(cfileDlg.GetPathName(),CFile::modeCreate|CFile::modeWrite);  
  10.         cfile.Write("hello,use CFileDialog!!!",strlen("hello,use CFileDialog!!!"));  
  11.         cfile.Close();  
  12.   
  13.     }  


 

[cpp]  view plain copy
  1. CFileDialog cfileDlg(TRUE);  
  2. cfileDlg.m_ofn.lpstrTitle="我的打开对话框";  
  3. cfileDlg.m_ofn.lpstrFilter="Test File(*.txt)\0*.txt\0All File(*.*)\0*.*\0\0";//设置过滤器  
  4. if(IDOK==cfileDlg.DoModal())  
  5. {  
  6.     CFile cfile(cfileDlg.GetPathName(),CFile::modeRead);  
  7.       
  8.         char *ch;  
  9.         int len=cfile.GetLength();  
  10.         ch=new char[len+1];  
  11.         cfile.Read(ch,len);  
  12.         ch[len]=0;  
  13.         cfile.Close();  
  14.         MessageBox(ch);  
  15.   
  16.       
  17. }  


跟CColorDialog和CFontDialog一样,都是模态对话框

下面讲的是 如何修改与获取win.ini文件的内容,如何修改获取删除注册表的内容:

在CXXAPP文件的InitInstance函数中添加

[cpp]  view plain copy
  1. ::WriteProfileString("afei@qq.com","admin","maikefeng");  

将段名为afei@qq.com,键值为amdin,value为maikefeng

 

[cpp]  view plain copy
  1. char ch[100];  
  2.     ::GetProfileString("afei@qq.com","admin","morenzhi",ch,100);  
  3.     AfxMessageBox(ch);  


或者:

[cpp]  view plain copy
  1. CString cstring;  
  2.     ::GetProfileString("afei@qq.com","admin","morenzhi",cstring.GetBuffer(100),100);  
  3.     AfxMessageBox(cstring);  

 

 

CXXAPP类中 继承了WriteProfileString和GetProfileString方法,跟WIN SDK的不一样,修改的是注册表

[cpp]  view plain copy
  1. SetRegistryKey(_T("Local AppWizard-Generated Applications"));  
  2.   
  3.     WriteProfileString("afei@qq.com","admin","maikefeng");  

其中,SetRegistryKey中的字符串的值是可以改变的

在Hkey Current user--->software---->




[cpp]  view plain copy
  1. void CFileTestView::OnXieruzhucebiao()   
  2. {  
  3.     // TODO: Add your command handler code here  
  4.       
  5.     HKEY hkey;  
  6.     ::RegCreateKey(HKEY_LOCAL_MACHINE,"software\\adminqq\\afei",&hkey);  
  7.     ::RegSetValue(hkey,NULL,REG_SZ,"6345",strlen("6345"));  
  8.     ::RegCloseKey(hkey);  
  9.   
  10. }  

 

[cpp]  view plain copy
  1. void CFileTestView::OnDuquzhucebiao()   
  2. {  
  3.     // TODO: Add your command handler code here  
  4.       
  5.     LONG ivalue;  
  6.     ::RegQueryValue(HKEY_LOCAL_MACHINE,"software\\adminqq\\afei",NULL,&ivalue);  
  7.     char *ch=new char[ivalue];  
  8.     ::RegQueryValue(HKEY_LOCAL_MACHINE,"software\\adminqq\\afei",ch,&ivalue);  
  9.     MessageBox(ch);  
  10. }  

可以调整类型的,自己查MSDN

[cpp]  view plain copy
  1. void CFileView::OnRegWrite()   
  2. {  
  3.     // TODO: Add your command handler code here  
  4.     HKEY hKey;  
  5.     DWORD dwAge=30;  
  6.     RegCreateKey(HKEY_LOCAL_MACHINE,"Software\\http://www.sunxin.org\\admin",&hKey);  
  7.     RegSetValue(hKey,NULL,REG_SZ,"zhangsan",strlen("zhangsan"));  
  8.     RegSetValueEx(hKey,"age",0,REG_DWORD,(CONST BYTE*)&dwAge,4);  
  9.     RegCloseKey(hKey);  
  10. }  


 

[cpp]  view plain copy
  1. void CFileView::OnRegRead()   
  2. {  
  3.     // TODO: Add your command handler code here  
  4. /*  LONG lValue; 
  5.     RegQueryValue(HKEY_LOCAL_MACHINE,"Software\\http://www.sunxin.org\\admin", 
  6.         NULL,&lValue); 
  7.     char *pBuf=new char[lValue]; 
  8.     RegQueryValue(HKEY_LOCAL_MACHINE,"Software\\http://www.sunxin.org\\admin", 
  9.         pBuf,&lValue); 
  10.     MessageBox(pBuf);*/  
  11.     HKEY hKey;  
  12.     RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\http://www.sunxin.org\\admin",&hKey);  
  13.     DWORD dwType;  
  14.     DWORD dwValue;  
  15.     DWORD dwAge;  
  16.     RegQueryValueEx(hKey,"age",0,&dwType,(LPBYTE)&dwAge,&dwValue);  
  17.     CString str;  
  18.     str.Format("age=%d",dwAge);  
  19.     MessageBox(str);  
  20. }  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值