MFC文件操作

文件操作:二进制文件和文本文件的区别。二进制文件将数据在内存中存在的模式原封不动的搬到文件中,而文本文件是将数据的asc码搬到文件中。首先做一个读写文件的菜单,在CxxView里响应1.C的方式:fw

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

文件操作:二进制文件和文本文件的区别。二进制文件将数据在内存中存在的模式原封不动的搬到文件中,而文本文件是将数据的asc码搬到文件中。
首先做一个读写文件的菜单,在CxxView里响应
1.C的方式:
fwrite:
size:Item size in bytes 每次写多少个字节
count:Maximum number of items to be written ,总共写几次。

FILE *p;
p=fopen(“c://1.txt”,”w”);
fwrite(“abc”,1,4,p);
fclose(p);
由于我们打开文件后文件就被映射到内存中的缓存中,我们对文件所做的操作都是在内存中完成的,如果我们不关闭文件,则内存中对文件所做的修改就不会反映(保存)到硬盘中,除非你把当前一个应用程序关闭,这是会自动执行文件关闭的操作。
fflush可以在文件不关闭的情况下将一个流(缓冲区)当中的数据清空,这里的清空是把缓冲区的数据输出到硬盘。这样可以达到边写边输出的效果。
FILE* pFile=fopen(“c://1.txt”,”w”); 
fwrite(“何问起网”,1,strlen(“何问起网“),pFile);
//fclose(pFile);
fflush(pFile);
fwrite(“how are you”,1,strlen(“何问起网”),pFile);
fflush(pFile);
fclose(pFile);
我们发现下一次的“h”是写在了上次的“心”后面了,这是因为,对于文件来说它有一个文件字符位置的指针,这个指针不同于文件的指针,是文件结构中这个char *_ptr;成员。当我们写完“心”字后,这个指针就在“心” 字后,所以下次写“h”的时候就是在“心”的后面写。如果想将第二句在“维”的前面输出,则要移动文件的位置指针,用fseek
FILE* pFile=fopen(“c://1.txt”,”w”); 
fwrite(“何问起网”,1,strlen(“何问起网”),pFile);
//fclose(pFile);
fflush(pFile); 
fseek(pFile,0,SEEK_SET);
fwrite(“北京”,1,strlen(“北京”),pFile);
fflush(pFile);
fseek(pFile,0,SEEK_END);
CString str;
str.Format(“文件大小:%d”,ftell(pFile));
MessageBox(str);
fclose(pFile);
读文件
FILE* pFile=fopen(“c://1.txt”,”r”); 
char buf[100];
fread(buf,1,100,pFile);//虽然读出的数据超出了实际字符串的长度,但输出时还是找’/0’
MessageBox(buf);
fclose(pFile);
出现了乱码,是因为输出文件的时候没有及时找到’/0’.将写文件的strlen改为sizeof
文件读写函数需要读写的时候将’/0’带上,它类似于printf和strlen等函数以’/0’作为函数结束表示。
乱码的解决也可以用
FILE* pFile=fopen(“c://1.txt”,”r”); 
char buf[100];
fseek(pFile,0,SEEK_END);
long len=ftell(pFile);
rewind(pFile);
fread(buf,1,len,pFile);
buf[len]=0;
MessageBox(buf);
fclose(pFile);
第三种方法:
FILE* pFile=fopen(“c://1.txt”,”r”); 
char buf[100];
memset(buf,0,100);//可以用任意的字符来填充这个内存块。
ZeroMemory(buf,100);// 只能用‘/0’字符来填充这个内存块。
fread(buf,1,100,pFile);
MessageBox(buf);
fclose(pFile);
2.C++的方式:#include “fstream.h”
写:
ofstream ofs(“c://1.txt”);
ofs.write(“何问起网”,sizeof(“何问起网”));
ofs.close();//最好自己将文件关掉,不关也行,这个filebuf对象的析构函数为你关。
读:
ifstream ifs(“c://1.txt”);
char buf[100];
ifs.read(buf,100);
MessageBox(buf);
当我们写的代码改为                          
ofstream ofs(“c://1.txt”);
char str[3];
str[0]=’a’;
str[1]=10;
str[2]=’b’;
ofs.write(str,sizeof(str));
   ofs.seekp(0);
ofs.write(“china”,sizeof(“china”));
发现此时默认按照文本写和读的时候,文件的大小不符。
这是因为在用文本文件方式读写的时候,碰到了asc码为10的字符,都将被转换,写文件的时候将10前面加上13写到了文件中,读文件读到13和10,将这两个字符换成一个10.注意在用ultraEdit看的时候不要转成DOS格式。
如果以二进制文件(ios::binary)进行读写的时候就没有这种问题存在。不做任何的转换。
C++的文件操作打开文件是在构造函数里完成,关闭文件是在析构函数里完成。
3. MFC的方式:
I. 写文件:
CFile f(“c://1.txt”,CFile::modeWrite|CFile::modeCreate);
f.Write(“hello”,5);
a.几个标志的作用:
  CFile::modeCreate:没有指定的文件就产生一个新文件,有就打开该文件,并将它裁剪到0;
  CFile::modeNoTruncate :打开文件时不裁剪到0;
b.写数据到文件末尾:
CFile f(“c://1.txt”,CFile::modeWrite|CFile::modeCreate|
CFile::modeNoTruncate);
      f.SeekToEnd();
f.Write(“hello”,5);
//file.Close();如果我不关闭的话,其析构函数会为我关闭。
II. 读文件:
CFile f(“c://1.txt”,CFile::modeRead);
char buf[10];
memset(buf,0,10);
f.read(buf,5);
MessageBox(buf);
III. 文件对话框:
保存对话框:

CFileDialog fdlg(false);
//fdlg.m_ofn.lpstrTitle=”何问起造!”;
fdlg.m_ofn.lpstrDefExt=”txt”;
fdlg.m_ofn.lpstrFilter=”文本文件 (*.txt)/0*.txt/0所有文件 (*.*)/0*.*/0/0″;
if(IDOK==fdlg.DoModal())
{
//MessageBox(fdlg.GetFileName());
CFile file(fdlg.GetFileName(),CFile::modeCreate|CFile::modeWrite);
file.Write(“何问起网”,sizeof(“何问起网”));
file.Close();
}

打开对话框:

CFileDialog fdlg(true);
//fdlg.m_ofn.lpstrTitle=”何问起造!”;
fdlg.m_ofn.lpstrFilter=”文本文件 (*.txt)/0*.txt/0所有文件 (*.*)/0*.*/0/0″;
if(IDOK==fdlg.DoModal())
{  
CFile file(fdlg.GetFileName(),CFile::modeRead);
char buf[100];
file.Read(buf,100);
MessageBox(buf);
}
2. 文本文件和二进制文件的区别:
文件文件是一种特殊的二进制文件,当它遇到回车键10时,写入文件时会自动地在它的前面加一个13,而读出文件时遇到13 10 的组合时,又把它还原到10。而二进制文件就是把数据原封不动的写入文件,原封不动的再读取出来,没有文本文件的这种转换操作。
下面的代码演示了之间的这种区别:
  写入文件时:
   ofstream f(“c://1.txt”);
   char buf[3];
   buf[0]=’a’;
   buf[1]=’/n’;
   buf[2]=’b’;
   f.write(buf,3);
读出文件时:
ifstream f(“c://1.txt”);
f.setmode(filebuf::binary);
char buf[5];
memset(buf,0,5);
f.read(buf,5);
CString str;
str.Format(“%d,%d,%d,%d”,buf[0],buf[1],buf[2],buf[3]);
MessageBox(str);
    在写入文件时不指定格式,文件将按文本格式存储,此时读出文件时指定二进制格式,读出的数据如下图:
      
如果注释f.setmode(filebuf::binary);语句,文件将按文本文件读出,如下图:

二、 注册表的操作
1. 读写win.ini文件:
使用API的GetProfileInt和WriteProfileString来实现一个保存窗口大小的例子。
在CMainFrame的
void CMainFrame::OnDestroy() 
{
CFrameWnd::OnDestroy();

// TODO: Add your message handler code here
CRect rect;
GetWindowRect(&rect);
CString str;
str.Format(“%d”,rect.Width());
WriteProfileString(“窗口尺寸”,”宽度”,str);
str.Format(“%d”,rect.Height());
WriteProfileString(“窗口尺寸”,”高度”,str);
}

在CMainFrame的
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
   return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.cx=GetProfileInt(“窗口尺寸”,”宽度”,100);
cs.cy=GetProfileInt(“窗口尺寸”,”高度”,100);
return TRUE;
}

演示使用API的GetProfileString.对于它的第四个参数lpReturnedString需要添一个char*来返回。这里不能添CString对象来返回,这是一个特殊的地方。别的函数一般要char*的时候都可以用CString对象来代替。
这里我们用CString的GetBuffer来添这个char*。
A CString object consists of a variable-length sequence of characters.
因为一个字符串对象由一序列长度可变的字符组成。

Returns a pointer to the internal character buffer for the CString object. The returned LPTSTR is not const and thus allows direct modification of CString contents.
返回一个CString对象内部字符的缓冲区(字符数组)的指针,这个返回的指针不是一个常量的指针,因而允许直接修改指针所指向的CString对象的内容。这个指针和CString内部字符数组的地址是相等的。

If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before using any other CString member functions.
如果你使用这个通过GetBuffer返回的指针改变了字符串的内容,你在使用CString其他成员函数之前必须调用ReleaseBuffer。

在CWinApp的InitInstance里
CString str;
::GetProfileString(“窗口尺寸”,”高度”,”无值”,str.GetBuffer(100),100);
AfxMessageBox(str);
下面测试CWinApp的WriteProfileString,GetProfileString。
对于WriteProfileString有段说明
· In Windows NT, the value is stored to a registry key.
· In Windows 3.x, the value is stored in the WIN.INI file. 
· In Windows 95, the value is stored in a cached version of WIN.INI
在CWinApp的InitInstance里
WriteProfileString(“收藏”,”vc++”,”菜鸟”);

CString str;
str=GetProfileString(“收藏”,”vc++”,”无效值”);
AfxMessageBox(str);
所以这里写的话是写到了HKEY_CURRENT_USER/Software/Local AppWizard-Generated Applications/MyFile/维新里。

实现一个简单的计数器,来限制软件的使用次数:
SetRegistryKey(_T(“myboleApp”));
int x=GetProfileInt(“test”,”times”,0);
if(x>=5)
   return false;
WriteProfileInt(“test”,”times”,++x);
CString str;
str.Format(“你还能使用%d次”,5-x);
AfxMessageBox(str);

2. 读写WIN32注册表,做两个菜单进行注册表的读写操作,写的时候先打开所要操作键,也就是返回操作键的句柄用RegCreateKey(这个句柄包含主键和子键,第一个参数可以是一个已打开的句柄或者一个预定义的保留的句柄值,如果是前面这个已打开的句柄,那么可以根据这个已打开句柄和后面子键的参数,在这个已打开键的下面创建一个新的句柄),然后根据得到的这个句柄去读写。
在使用RegSetValue进行写操作的时候,写的类型必须是REG_SZ,这个类型可以理解成已’/0’结尾的字符串,如果我们想写别的数据类型,使用RegSetValueEx.
The RegSetValue function sets the data for the default or unnamed value of a specified registry key. The data must be a text string.
RegSetValue函数为默认的或没有名字的指定的注册表键设置数据,这个数据必须是字符串。
RegSetValue最后一个参数不包括’/0’
使用新函数在注册表任意位置读写:
写:
HKEY hKey;
RegCreateKey(HKEY_LOCAL_MACHINE,”software//收藏”,&hKey);
//RegSetValue(hKey,NULL,REG_SZ,”WeiXin”,6);
//RegSetValue(hKey,”课程”,REG_SZ,”WeiXin”,6);
DWORD i=100;//下面的参数要的是地址,所以这里要定义这个变量
RegSetValueEx(hKey,”JSP”,NULL,REG_DWORD,(CONST BYTE*)&i,4);
RegCloseKey(hKey);
读:in bytes以字节为单位

读一个默认键的值:
char *buf;
long len;
RegQueryValue(HKEY_LOCAL_MACHINE,
“software//何问起网//mylyhu//abc”,NULL,&len);
buf=new char[len];
RegQueryValue(HKEY_LOCAL_MACHINE,
“software//何问起网//mylyhu//abc”,buf,&len);
MessageBox(buf);
delete [] buf;

RegQueryValue参数说明:
If lpValue is NULL, and lpcbValue is non-NULL, the function returns ERROR_SUCCESS, and stores the size of the data, in bytes, in the variable pointed to by lpcbValue. This lets an application determine the best way to allocate a buffer for the value’s data. 
如果lpValue是NULL,并且lpcbValue不是NULL,这个函数返回ERROR_SUCCESS,并且通过lpcbValue所代表这个变量的指针存储数据的字节单位的的大小,这是让一个应用程序按照最好的方式去为查询值的数据分配空间

读一个有名字的键的值。
HKEY hKey;
RegCreateKey(HKEY_LOCAL_MACHINE,”software//维新”,&hKey); 
DWORD dwType;
DWORD data;
DWORD len=4;
RegQueryValueEx(hKey,”JSP”,NULL,&dwType,(BYTE*)&data,&len);
CString str;
str.Format(“%d”,data);
MessageBox(str);
::RegCloseKey(hKey);

锁注册表:
HKEY hKey;
RegCreateKey(HKEY_CURRENT_USER,”software//microsoft//windows//currentversion//policies//system”,&hKey);
DWORD x=1;
RegSetValueEx(hKey,”DisableRegistryTools”,0,REG_DWORD,(CONST BYTE*)&x,4);
RegCloseKey(hKey);

解注册表
HKEY hKey;
RegCreateKey(HKEY_CURRENT_USER,”software//microsoft//windows//currentversion//policies//system”,&hKey);
DWORD x=0;
RegSetValueEx(hKey,”DisableRegistryTools”,0,REG_DWORD,(CONST BYTE*)&x,4);
RegCloseKey(hKey);

推挤:http://www.cnblogs.com/roucheng/p/cppyiwei.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/120367.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 迅雷种子为什么php文件后缀,迅雷BT文件后缀是什么?[通俗易懂]

    迅雷种子为什么php文件后缀,迅雷BT文件后缀是什么?[通俗易懂]你是否正在寻找关于文件后缀的内容?让我把最实时的东西奉献给你:迅雷BT文件后缀是什么?BT是一个后缀名为.torrent的小文件,它里面保存了服务器地址、要下载的文件的大孝分成的块数以及各种下载参数设置,这个文件一般在20k-100k大小,可以把*.php直接改成*.torrent试试!要么就是文件制作出错!在去这个页面下载一次,当弹出迅雷下载的时候点取消.让Windows下载.会出现保存对话框…

    2025年8月11日
    6
  • uml用例图详解_uml模型图

    uml用例图详解_uml模型图用例图的含义由参与者(Actor)、用例(UseCase)以及它们之间的关系构成的用于描述系统功能的动态视图称为用例图。其中用例和参与者之间的对应关系又叫做通讯关联(CommunicationAssociation)。用例图的作用用例图是需求分析中的产物,主要作用是描述参与者与和用例之间的关系,帮助开发人员可视化地了解系统的功能。借助于用例图,系统用户、系统分析人员、系统设计人员、领…

    2025年9月27日
    4
  • 可视化数据库设计软件有哪些_数据库可视化编程

    可视化数据库设计软件有哪些_数据库可视化编程学习目标:C#数据库应用程序的开发环境的构成服务器资源管理器类型化数据集创建简单的数据库应用程序水晶报表Notes:类型化数据集利用服务器资源管理器建立数据连接利用服务器资源管理器可执行的任务如下:1)打开数据连接。2)登录到服务器上,并显示服务器的数据库和系统服务,包括事件日志、消息队列、性能计数器、系统服务和SQL数据库。3)查看关于可用Web服务的信息以及使信息…

    2022年4月20日
    55
  • 《语音信号处理》 语音识别章节 读书笔记

    《语音信号处理》 语音识别章节 读书笔记P34HMM是一个双内嵌式随机过程,由两个随机过程组成:一个是状态转移序列,对应单纯markov过程;另一个是每次转移时输出的符号组成的符号序列。(这个也是随机的,理解为不知道状态序列,也不知道输出符号序列。。。)P130:模板(模型)Mi,即i单词的均值和协方差矩阵。P135:语音信号的特征矢量序列的集合作为观察值序列O=O1,O2,…OTP136:声学…

    2022年5月26日
    54
  • java map()_java之map的基本介绍

    java map()_java之map的基本介绍map简介在讲解Map排序之前,我们先来稍微了解下map。map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等。其中这四者的区别如下(简单介绍):HashMap我们最常用的Map,它根据key的HashCode值来存储数据,根据key可以直接获取它的Value,同时它具有很快的访问速度。HashMap最多只允许一条记录的…

    2022年7月7日
    28
  • 浮动工具栏在哪里_设置面板的布局方式为边界布局

    浮动工具栏在哪里_设置面板的布局方式为边界布局使用BCG界面库,工具栏的一些用法就和MFC不一样了,MFC的CFrameWnd直接有一个设置浮动工具条位置的函数可以调用,而BCG没有,因为其对于TOOLBAR的底层实现和MFC那一套实现流程完全不同。BCG库的代码设置浮动工具栏的位置,又折腾了我几个小时,通过看其源码加改调用函数改参数调试,最后终于出来了,也不知此法好不好。代码如下: voidCMainFrame::RePos

    2022年10月8日
    8

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号