• CFileDialog类与16进制格式的dat文件


    要将数据保存为.dat文件,而且是16进制的数字,怎么保存?

    要读取.dat文件,文件是16进制的,怎么读取?

    用CFileDialog类可以得到【保存】和【打开】的对话框,具体怎么保存和读取,需要我们自己写代码了。这里,和大家分享一下,怎么保存16进制的文件到.dat中?怎样从.dat中读取你保存的16进制数字?

    对于读取到的这些数据,你想做什么,可以因人而异。您可以在看懂本篇文章的基础上,举一反三。

    本人也是菜鸟,也是参考了很多论坛上高手的代码。代码虽然能通过编译,可能不是最好的。欢迎大家提出意见。

    一、保存16进制数字的.dat文件:

     1     // 文件的保存
     2     // 通过CFileDialog 类,保存文件
     3     CFileDialog fileDlg(FALSE, "dat", "btypetb");
     4     fileDlg.m_ofn.lpstrTitle="请保持设置";
     5     fileDlg.m_ofn.lpstrFilter=".dat files(*.dat)*.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    }

     虽然代码里面有注释,我这里还是再解释一部分代码:

    1.代码第3行,第一个参数false,表示我们需要一个【保存】的对话框。如果传递true,那么你将得到【打开】的对话框。第二个参数是保存文件默认的文件格式,这里是dat格式。第三个参数比较重要了,是你默认的文件名。参数传递的个数,不是固定的,你可以传入1个参数,也可以传入多个参数,根据个人需要而定。更多解释,您可以参考MSDN。

    2.代码第5行,这是设置格式过滤器。我也是参考孙鑫的《VC++深入详解》第12章中提到的文件过滤器来做的。下面的代码是教程中的代码,您可以自己手动设置几次,弄懂之后,修改为自己需要的就可以了。

    1     CFileDialog fileDlg(TRUE);
    2     fileDlg.m_ofn.lpstrTitle="我的文件打开对话框";
    3     fileDlg.m_ofn.lpstrFilter="Text Files(*.txt)*.txtAll Files(*.*)*.*";
    View Code

    3.代码第7行到第13行,是参考了网上一位高手的回帖。

    4.注意第26行代码里面的参数。这里是设置为二进制的写。您可以参考MSDN了解跟多信息。

    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;

    //上面的赋值代码都是合法的。

    // 这样做就很好了。还需要啥函数来转换。。

    // 活学活用啊。。。我当时钻牛角尖了。

    二、读取16进制数字的.dat文件:

     1     CFileDialog fileDlg(TRUE);
     2     fileDlg.m_ofn.lpstrTitle="打开我的dat文件";
     3     fileDlg.m_ofn.lpstrFilter=".dat files(*.dat)*.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];

    总结:感谢,感谢网上各位高手。

    这里是几个值得参考的帖子:

    http://bbs.csdn.net/topics/300048398

    http://bbs.csdn.net/topics/320263449

  • 相关阅读:
    SC Alibaba20211102 Nacos 微服务框架结构 SerivceImplOrder <OpenFeign> SerivceImplMember 群
    SC Alibaba20211030 Nacos 微服务框架结构 SerivceImplOrder <OpenFeign> SerivceImplMember
    SC Alibaba20211028 Nacos 微服务框架结构 SerivceImplMember
    SC Alibaba20211022 Nacos 负载均衡 rest|feign(ribbon) ----@loadbalancer
    springboot启动多个实例
    SC Alibaba20211019 Nacos 手写LoadBalancer LoadBalancerClient
    SC Alibaba20211018 Nacos discoveryCient-restTemplate调用
    SC Alibaba20211017 Nacos 命令 测试服务、配置功能 postman
    mysql性能测试(SQL_CALC_FOUND_ROWS)
    GIS相关的一些常用操作(持续记录...)
  • 原文地址:https://www.cnblogs.com/music-liang/p/3269243.html
Copyright © 2020-2023  润新知