要将数据保存为.dat文件,并且是16进制的数字,怎么保存?html
要读取.dat文件,文件是16进制的,怎么读取?数组
用CFileDialog类能够获得【保存】和【打开】的对话框,具体怎么保存和读取,须要咱们本身写代码了。这里,和你们分享一下,怎么保存16进制的文件到.dat中?怎样从.dat中读取你保存的16进制数字?ide
对于读取到的这些数据,你想作什么,能够因人而异。您能够在看懂本篇文章的基础上,触类旁通。函数
本人也是菜鸟,也是参考了不少论坛上高手的代码。代码虽然能经过编译,可能不是最好的。欢迎你们提出意见。spa
1 // 文件的保存 2 // 经过CFileDialog 类,保存文件 3 CFileDialog fileDlg(FALSE, "dat", "btypetb"); 4 fileDlg.m_ofn.lpstrTitle="请保持设置"; 5 fileDlg.m_ofn.lpstrFilter=".dat files(*.dat)\0*.dat"; 6 7 // 得到相对路径(网上找的的这个方法) 8 // 先获取当前正在运行的程序的路径,而后将该路径拿来本身用 。 9 TCHAR szFilePath[MAX_PATH + 1]; 10 GetModuleFileName(NULL, szFilePath, MAX_PATH); 11 (_tcsrchr(szFilePath, _T('\\')))[1] = 0; 12 CString strtemp = szFilePath; 13 fileDlg.m_ofn.lpstrInitialDir = strtemp; 14 15 // 定义fpFile文件指针 16 FILE *fpFile; 17 18 // 若是用户点击了保存按钮,则执行if语句内的操做 19 if (IDOK == fileDlg.DoModal()) 20 { 21 // 获取用户输入的文件名。有2种方法 22 CString fileName = fileDlg.GetFileName(); 23 // CString fileName = fileDlg.m_ofn.lpstrFileTitle; 24 25 // fopen的第一个参数是带路径的文件名。 26 if ((fpFile = fopen(strtemp+"\\"+fileName, "w+b")) == NULL) 27 return ; 28 fwrite (datBuffer, 2 + m_DevCounts * 2, 1, fpFile); 29 fclose(fpFile); 30 }
虽然代码里面有注释,我这里仍是再解释一部分代码:.net
1.代码第3行,第一个参数false,表示咱们须要一个【保存】的对话框。若是传递true,那么你将获得【打开】的对话框。第二个参数是保存文件默认的文件格式,这里是dat格式。第三个参数比较重要了,是你默认的文件名。参数传递的个数,不是固定的,你能够传入1个参数,也能够传入多个参数,根据我的须要而定。更多解释,您能够参考MSDN。指针
2.代码第5行,这是设置格式过滤器。我也是参考孙鑫的《VC++深刻详解》第12章中提到的文件过滤器来作的。下面的代码是教程中的代码,您能够本身手动设置几回,弄懂以后,修改成本身须要的就能够了。code
1 CFileDialog fileDlg(TRUE); 2 fileDlg.m_ofn.lpstrTitle="个人文件打开对话框"; 3 fileDlg.m_ofn.lpstrFilter="Text Files(*.txt)\0*.txt\0All Files(*.*)\0*.*\0\0";
3.代码第7行到第13行,是参考了网上一位高手的回帖。orm
4.注意第26行代码里面的参数。这里是设置为二进制的写。您能够参考MSDN了解跟多信息。htm
5.看第28行代码。这是咱们的重点。文件操做3部曲:1.打开文件;2.Write/Read文件;3.关闭文件。
第28行代码中,第一个参数,是保存了这些16进制数字的数组,第2个参数,是数组的大小(为何个人第二个参数是这样样子的,您就没必要纠结了。这是我程序中的实际传递过来的参数。您能够根据实际状况来决定您的数组大小。);其余参数,参考MSDN。
datBuffer是这样定义的:BYTE datBuffer[200]; // 数组长度根据您我的实际来设置。
BYTE 是 unsigned char 类型 // 在你进行类型转换的时候,会颇有用
为何定义为BYTE就是能保存16进制数字了,其实我也不太清楚。
我也是在网上参考高手的代码,才实现上述功能的。刚才在网上又搜了一下,这里有个将BYTE和16进制之间的关系的文章,能够看看。
http://www.360doc.com/content/11/0222/22/4780948_95250828.shtml
回到文章中来,咱们就这么一 Write,就能成功生成16进制的.dat文件了。哈哈,是否是感受特厉害。。。。。。
在成功的同时,咱们也应该知道,其实仍是有一些知识点没有消化。。。欢迎高手指点。
.dat存储的时候,是以BYTE来存储的。说得通俗点,就是unsigned char 类型来存储的。
而个人原始数据是int类型。。。将int转为16进制的BYTE。这里,不须要用到什么函数。
直接,强制类型转换。便可。不须要想太多、太复杂。
int a1=10, a2=192; BYTE arr[4] = {0}; arr[0] = (unsigned char)a1; arr[1] = (unsigned char)a2; arr[2] = 0xaa;
//上面的赋值代码都是合法的。
// 这样作就很好了。还须要啥函数来转换。。
// 活学活用啊。。。我当时钻牛角尖了。
1 CFileDialog fileDlg(TRUE); 2 fileDlg.m_ofn.lpstrTitle="打开个人dat文件"; 3 fileDlg.m_ofn.lpstrFilter=".dat files(*.dat)\0*.dat"; 4 5 // 得到相对路径(网上找的的这个方法) 6 // 先获取当前正在运行的程序的路径,而后将该路径拿来本身用 。 7 TCHAR szFilePath[MAX_PATH + 1]; 8 GetModuleFileName(NULL, szFilePath, MAX_PATH); 9 (_tcsrchr(szFilePath, _T('\\')))[1] = 0; 10 CString strtemp = szFilePath; 11 fileDlg.m_ofn.lpstrInitialDir = strtemp; 12 13 // 定义fpFile文件指针 14 FILE *fpFile; 15 16 if (IDOK == fileDlg.DoModal()) 17 { 18 long Filelen; 19 // 注意细节 20 unsigned char* buffer; 21 22 CString fileName = fileDlg.GetPathName(); 23 24 if ((fpFile = fopen(fileName, "rb")) == NULL) 25 return ; 26 27 // 文件指针到文件尾 28 fseek(fpFile, 0, SEEK_END); 29 // 读取文件长度 30 Filelen = ftell(fpFile); 31 // 分配内存 32 // 按文件长度申请内存空间 33 buffer = (unsigned char*)malloc(Filelen); 34 35 // 文件指针指到文件头 36 fseek(fpFile, 0, SEEK_SET); 37 // 读取文件到申请的内存 38 fread(buffer, 1, Filelen, fpFile); 39 fclose(fpFile); 40 41 // 到这里,其实buffer里面已经存放了你须要的数据,你能够作你须要的操做了。 42 // 这里,将读取的16进制数字,在MessageBox中显示出来。 43 CString strResult; 44 for(int j=0; j<Filelen; j++) 45 { 46 CString s = ""; 47 s.Format("%2.2x ", buffer[j]); 48 strResult += s; 49 } 50 51 MessageBox(strResult); 52 }
1.代码第1行,这里传递的参数是TRUE。表示,咱们须要一个【打开】的对话框。
2.代码第20行,咱们定义的是 unsgined char* 类型的变量。
3.从代码第28行开始,是重点了。
4.在代码第24行中,设置了为二进制打开。
5.第38行代码,将数据读入到buffer中了。到此,你已经获得你想要的16进制数字了。你想怎么处理,能够根据实际状况来实际操做。这里再说一次,buffer定义的是unsigned char*类型,在进行强制类型转换的时候,会有用的。
6.在这里,咱们想将.dat文件里的16进制数字在MessageBox对话框中显示出来,咱们能够看第44行的代码。
若是你想将这些16进制数字显示出来的话,第41行到第51行的代码能够实现此功能。
若是你想将读取的16进制数字用做其余用途,我的是这么理解的。
经过第38行的代码,你的buffer数组中,已经存放了16进制的数字了。
16进制数字对我来讲,没多大用。(至少我当前程序中没有涉及到这方面的问题)
我当时是这么作的,将16进制的数字转换为整型的数字。整型是你们都熟悉的类型,而后你就能够想干什么就干什么了。
(若是您在数值之间的转换方面遇到了一些问题,我的建议仍是多看看这些类型的定义(通常,C++基础教程里面都会讲到的,温故而知新)。好比BYTE实际上是unsigned char类型,char和int之间是能够相互转换的,可是要注意char的范围,也要知道,unsgined char 和 char 做用的范围不一样,当心数据丢失哦。)
int Num1, Num2; Num1 = buffer[0]; Num2 = buffer[1];
总结:感谢,感谢网上各位高手。
这里是几个值得参考的帖子: