引用 | 編輯
csr
2011-05-29 21:47 |
樓主
▼ |
||
x0
/* 程式名稱 : ch13_22.c *//* 隨機讀取某檔案的 16 位元資料 */ #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <math.h> int main(int argc, char *argv[]) { long pos; int fd; int sector; int totalread,totaldigit,totalchar; int i,j; char buffer;請教大大,這64是否代表64位元嗎? fd = open(argv,O_RDONLY | O_BINARY); while ( 1 ) { printf("輸入磁區 ");這裡的磁區,怎會是檔案的第一行,而不是磁碟的第x磁區呢? scanf("%d",§or); if ( sector < 0 ) { printf("結束隨機讀取資料 \n"); break; } pos = (long) sector * 64;請教這裡64 .. 訪客只能看到部份內容,免費 加入會員 x0
|
引用 | 編輯
ebolaman
2011-06-02 21:28 |
1樓
▲ ▼ |
應該是這樣,如果有錯誤還請大家指教 我最近才剛學 C 而已,不是很熟... buffer 一次讀 64 個位元組,就是以上的圖中,四個 16 bytes 的橫框框的範圍 然後以 char 一位元組為單位讀取 buffer[i*16+j] ,i 是小藍框框的左邊起始點 位移量,而 j 是在 小藍框框 內的位移量 我又畫了一張 我看了許久,他好像是要模擬 UltraEdit 那樣,左邊顯示 16 個 %3x 的 16 位元碼,然後右邊顯示 16 個 %c 的字元,接著換行 讀取是一次讀 64 個位元組 但是顯示的時候一行只顯示 16 個位元組,你也可以把它改成 32 個位元組 所以是把一次的讀取量 切成 4 塊來顯示 還有,buffer[64] 是 64 位元組,而非位元,C 裡面像是 sizeof() 得到的都是 "位元組",就是 8 個位元組成的 1 byte = 8 bits x3 |
引用 | 編輯
ebolaman
2011-06-03 18:46 |
3樓
▲ ▼ |
||||||||||
下面是引用 csr 於 2011-06-03 10:44 發表的 : 實作的話會更清楚,我們就拿我從 DesktopNexus 下載的桌布來當作 argv[1] 的字串目標 請將 圖片 Chromatic_link_by_k3_studio.jpg (附在此文章最下面) 放置到工作目錄下 另外請下載一套免費的 文字/十六進位 編輯軟體 (建議下載 Portable 的):RJ TextEd 點選底下的 Editor 並將這張桌布 直接拖曳進去,就可以檢視 十六進位碼 這是我 修改後的原始碼,用這個比較貼近 軟體顯示的方法: 複製程式 #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <math.h> int main(int argc, char *argv[]) { long pos; int fd; int sector; int totalread,totaldigit,totalchar; int i,j; char buffer[64]; argv[1]="Chromatic_link_by_k3_studio.jpg"; fd = open(argv[1],O_RDONLY | O_BINARY); while ( 1 ) { printf("輸入磁區 : "); scanf("%d",& sector); printf("\n"); if ( sector < 0 ) { printf("結束隨機讀取資料 \n"); break; } pos = (long) sector * 64; if ( lseek(fd,pos,SEEK_SET) == -1 ) { printf("隨機讀取資料錯誤 \n"); break; } /* 讀取 64 位元組資料如果讀不到這麼多表示已讀到檔案末端 */ if ( ( totalread = read(fd,buffer,64) ) != 64 ) printf("EOF : end of file.... \n"); totalchar = totaldigit = totalread; for ( i = 0; i < ceil((float)totalread / 16); i++ ) { for ( j = 0; j < 16; j++ ) { totaldigit--; if ( totaldigit < 0 ) /* 無資料則列空白 */ printf(" "); else /* 否則輸出 16 進位值 */ printf("%02X",buffer[i*16+j]<0 ? 255-(~buffer[i*16+j]) : buffer[i*16+j]); if (j&1==1) printf(" "); } printf(" "); /* 16 進位值和字元間的空白 */ for ( j = 0; j < 16; j++ ) { totalchar--; if ( totalchar < 0 ) printf(" "); /* 輸出完成後用空白取代 */ else if ( isprint(buffer[i*16+j]) ) printf("%c",buffer[i*16+j]);/*輸出字元*/ else /* 非字元則用 . 取代 */ printf("."); } printf("\n"); } printf("\n"); } close(fd); return 0; } (請用平面式 左到右 來想像檔案中的位元組) 首先,磁區開始 因為 lseek(fd,pos,SEEK_SET) 而被設定 位移量 將從 SEEK_SET 當作基準點 磁區為什麼要乘以 64? 因為他設定 buffer 一次要讀 64 個位元組,當然也可以設定不要乘以 64 那麼你輸入磁區的時候就要打 64, 128, 192 豈不是很麻煩 讀了 檔案中某一塊 64 的位元組後,接下來程式就是要顯示 這64個位元組資料 是什麼東西 他很想要模擬 UltraEdit 那樣一行顯示 16 個 16進位碼 請注意底下的像是 FFD8 其實是 2 個位元組 組成的,原本是要顯示 FF D8 但我想把他合在一起 十六進位的 FF 就是 十進位的 255 剛好是 2 的 8 次方-1 ,這就是 1 位元組有8個位元裝得下最大的數字 (unsigned) (最小是 0) 至於接下來除以 16 就是不想要一行 顯示 64 個,這樣會超出視窗範圍 因此他將 64 切成 4 塊 (顯示會顯示 4 行) 來顯示,64 / 4 = 16 ,這就是 16 的由來 至於 i*16+j 則是在 64 位元組內 的 位移量 在迴圈內 i*16+j 跑起來將會從 0~63 剛好一次讀一個位元組 至於達到 EOF 時候,buffer[i*16+j] 內是沒有讀到東西的 則將會顯示空白 你可以把 RJ TextEd 與 程式的結果來對照,請輸入 磁區 0 來比對比較輕鬆 將發現 16進位碼是 一模一樣 很有趣的,磁區2 裡面會看到 Adobe Photoshop CS2 甚至還有時間 他這張桌布是用哪個軟體編輯的還有儲存時間 都很明顯 Chromatic_link_by_k3_studio.jpg 桌布下載:
x3 |