- 鐵幣
- 1626 元
- 文章
- 1976 篇
- 聲望
- 747 枚
- 上次登入
- 15-1-17
- 精華
- 13
- 註冊時間
- 04-9-25
- UID
- 53390
|
要讀取檔案,就我從不會到會的經驗來看,有兩個重點
1.用fstream讀取檔案的方式。
2.了解要讀取的檔案的格式,這點比較重要。
- #include <fstream>
- //開檔
- char Name[]=“01.bmp”; //檔名。注意:這邊的NAME就是下一行的NAME,也就是要讀進去的檔案名稱,這名稱有包括副檔名。
- file.open(Name,參數);
- //讀檔
- file.read(變數,長度);//變數:將讀進去的資料以"變數"這麼名稱儲存。長度:要讀多少長度進去。
- 例如:
- file.read(line1,3);//這行的意思就是,讀進三個位元組的長度,將這三個位元組儲存在名稱為line1的陣列裡面。當然了,前面要先宣告一個名稱為line1的陣列才行阿。(char line1[32];)
- //寫檔
- file2.write(變數,長度);
- 例如:file.write(line1,3);//將陣列line1裡面的內容前面三個寫出到檔案裡面,詳細請見下面那一個完整的code。
複製代碼
這就是基本的fstream讀檔方式
因為在寫code時,你必須要知道這個檔案的哪幾個資料代表什麼,所以一定要先找出這個檔的組成結構。
之前有人回覆給我這個網址http://blog.pixnet.net/crazycat1130/post/1345538
內容不錯,必看!
除此網站之外,我們助教給我們的PDF也很詳細,也必看!
http://myweb.ncku.edu.tw/~f7495223/BMP_PDF.rar
附上一些fstream的開檔基本用法
- 開啟檔案時需使用open()這個函式。其格式如下。
- file.open(Name,nMode);
- ios::app:檔案開啟後,檔案指位器直接跳到末端位置,輸入的資料將接在檔案後面。。
- 􀂄ios::in:以輸入的方式處理檔案,這是ifstream的內定值。
- 􀂄ios::out:以輸出的方式處理檔案,這是ofstream的內定值。
- 􀂄ios::trunc:如果檔案已經存在,則內容將被清除。
- 􀂄ios::nocreate:如果檔案不存在,則會有錯誤訊息。
- 􀂄ios::noreplace:如果檔案已經存在,則會有錯誤訊息。
- 􀂄ios::binary:以二進位的形式來處理檔案。
- 所以整行可以寫成這樣
- file.open(Name,ios::in||ios::binary);
複製代碼
聽同學說處理非純文字的檔案都要加上ios::binary
上面的code"簡化"自助教給的PDF,因為那PDF裡面我看不懂的地方沒有PO上來。
在了解檔案結構之後,建議使用Ultra edit比對之前看到的教學,你會更清楚那是什麼意思!
Ultra edit下載:http://toget.pchome.com.tw/intro/business_wordprocessing/286.html
我覺得最重要的觀念是,「PDF中所寫的圖片資訊,在Ultra edit中,就是按照PDF中介紹的順序一路排列下來的。」(只有我覺得重要吧,同學都很直接這樣想.....)
意思就是,Ultra edit看到的一堆碼,前兩組就是代表檔案形式,接下來四組代表檔案大小,再來兩組是保留區‧‧‧以此類堆。
知道那些碼代表什麼之後,你還要會解讀!
例如:Ultra edit中顯示BMP圖檔最開頭兩組是42 4D,在ASCII(阿斯KEY)中,42=B,4D=M。
再來後兩組是大小的資訊,以一張17462位元組的BMP圖檔為例,第三跟第四組資訊為,36 44。
然後我們開啟小算盤,將它改為工程用的模式(檢視→工程型),在16進位下輸入3644,在轉換到10進位看,卻發現他不是17462。
可是當我們將16進位中的數字改為4436,再將它轉換到10進位,沒錯!它變成17462了。為什麼要從後面開始讀,這我也不知道,反正事實上就是這樣子,而這對我們寫code不會有什麼影響,只是寫出來讓大家輕鬆一下而已。
註:有時會有有一種很詭異的情況:「圖片大小跟儲存的資訊不一樣」。
例如原本我從助教那邊拿到的作業圖片是一張128*128的圖片,整張圖片加上一些檔頭資訊後,這張圖片按照36 44的計算,大小應該是17462位元組,但事實上。剛從助教那邊拿過來時他的大小是17464位元組(右鍵內容看到的),莫名奇妙多出兩個位元組。
原因不明,但是在將圖片用小畫家開啟,隨便做個動作然後復原它,然後另存新檔,檔案大小就變成了17462了(右鍵內容看到的)。
當它的大小是17464時,用Ultra edit看裡面的大小資訊,依然是36 44。
上面就夠讓一個新手頭痛啦!
再來就是整個code怎麼做了。
- #include <iostream>
- using std::cout;
- using std::cin;
- using std::endl;
- #include <fstream>
- using std::fstream;
- using std::ios;
- typedef unsigned char BYTE;
- typedef unsigned short WORD;
- typedef unsigned long DWORD;
- typedef long LONG;
- void main(){
- fstream file;
- int i,j;
- char fileName[32], RGBQUAD[4][256], PIXEL[128][128],temp[128][128];
-
- WORD bfType;
- DWORD bfSize;
- WORD bfReserved1;
- WORD bfReserved2;
- DWORD bfOffBits;
- DWORD biSize;
- LONG biWidth;
- LONG biHeight;
- WORD biPlanes;
- WORD biBitCount;
- DWORD biCompression;
- DWORD biSizeImage;
- LONG biXPelsPerMeter;
- LONG biYPelsPerMeter;
- DWORD biClrUsed;
- DWORD biClrImportant;
- //將資料從檔案輸入到記憶體
- cout << "Open FileName: ";
- cin >> fileName;
- file.open(fileName, ios::in|ios::binary);
- file.read((char*)&bfType, sizeof(WORD));
- file.read((char*)&bfSize, sizeof(DWORD));
- file.read((char*)&bfReserved1, sizeof(WORD));
- file.read((char*)&bfReserved2, sizeof(WORD));
- file.read((char*)&bfOffBits, sizeof(DWORD));
- file.read((char*)&biSize, sizeof(DWORD));
- file.read((char*)&biWidth, sizeof(LONG));
- file.read((char*)&biHeight, sizeof(LONG));
- file.read((char*)&biPlanes, sizeof(WORD));
- file.read((char*)&biBitCount, sizeof(WORD));
- file.read((char*)&biCompression, sizeof(DWORD));
- file.read((char*)&biSizeImage, sizeof(DWORD));
- file.read((char*)&biXPelsPerMeter, sizeof(LONG));
- file.read((char*)&biYPelsPerMeter, sizeof(LONG));
- file.read((char*)&biClrUsed, sizeof(DWORD));
- file.read((char*)&biClrImportant, sizeof(DWORD));
- file.read(RGBQUAD[0], sizeof(RGBQUAD));
- file.read(PIXEL[0], sizeof(PIXEL));
- file.close();
- //顯示檔案資訊
- cout << "FILE_HEADER\n"
- << "bfType=\t\t" << bfType << '\n'
- << "bfSize=\t\t" << bfSize << '\n'
- << "bfReserved1=\t" << bfReserved1 << '\n'
- << "bfReserved2=\t" << bfReserved2 << '\n'
- << "bfOffBits=\t" << bfOffBits << "\n\n"
- << "INFO_HEADER\n"
- << "biSize=\t\t" << biSize << '\n'
- << "biWidth=\t" << biWidth << '\n'
- << "biHeight=\t" << biHeight << '\n'
- << "biPlanes=\t" << biPlanes << '\n'
- << "biBitCount=\t" << biBitCount << '\n'
- << "biCompression=\t" << biCompression << '\n'
- << "biSizeImage=\t" << biSizeImage << '\n'
- << "biXPelsPerMeter=" << biXPelsPerMeter << '\n'
- << "biYPelsPerMeter=" << biYPelsPerMeter << '\n'
- << "biClrUsed=\t" << biClrUsed << '\n'
- << "biClrImportant=\t" << biClrImportant << "\n\n";
- //將圖片資訊暫存到TEMP裡面
- for(i=127;i>=0;i--){
- for(j=127;j>=0;j--){
- temp[i][j]=PIXEL[i][j];
- }
- }
- //將資訊反轉180度
- for(i=0;i<=127;i++){
- for(j=0;j<=127;j++){
- PIXEL[127-i][127-j]=temp[i][j];
- }
- }
- //將資料從記憶體輸出到檔案
- cout << "輸入旋轉後儲存的名稱:\t";
- cin >> fileName;
- file.open(fileName, ios::out|ios::binary);
- file.write((char*)&bfType, sizeof(WORD));
- file.write((char*)&bfSize, sizeof(DWORD));
- file.write((char*)&bfReserved1, sizeof(WORD));
- file.write((char*)&bfReserved2, sizeof(WORD));
- file.write((char*)&bfOffBits, sizeof(DWORD));
- file.write((char*)&biSize, sizeof(DWORD));
- file.write((char*)&biWidth, sizeof(LONG));
- file.write((char*)&biHeight, sizeof(LONG));
- file.write((char*)&biPlanes, sizeof(WORD));
- file.write((char*)&biBitCount, sizeof(WORD));
- file.write((char*)&biCompression, sizeof(DWORD));
- file.write((char*)&biSizeImage, sizeof(DWORD));
- file.write((char*)&biXPelsPerMeter, sizeof(LONG));
- file.write((char*)&biYPelsPerMeter, sizeof(LONG));
- file.write((char*)&biClrUsed, sizeof(DWORD));
- file.write((char*)&biClrImportant, sizeof(DWORD));
- file.write(RGBQUAD[0], sizeof(RGBQUAD));
- file.write(PIXEL[0], sizeof(PIXEL));
- file.close();
複製代碼
因為我要顯示檔案資訊
所以中間那一段比較複雜
一般要做特效的話,不必將中間檔案資訊的地方每一段都讀出來,直接將它讀做一個headfile就可以了。
要讀取的圖檔記得要放在你的專案所儲存的資料夾。
差不多就這樣吧。拜拜 |
|