天天看點

CFileDialog類與16進制格式的dat檔案一、儲存16進制數字的.dat檔案:二、讀取16進制數字的.dat檔案:

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章中提到的檔案過濾器來做的。下面的代碼是教程中的代碼,您可以自己手動設定幾次,弄懂之後,修改為自己需要的就可以了。

 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