2014-10-16 82 views
2

我試圖從一個命令行參數中讀取一次解析16個字節的文件。我將字節存儲在一個unsigned char數組中。然後,我試圖以HEX格式打印元素,然後,如果它們是可打印字符,我正在打印它們,如果不是,我打印一個點「。」我也想打印每個新行上文件起始字節的偏移量,但是我希望在開始處理之前讓剩下的部分工作。我遇到的問題是我正在閱讀的文件不是打印文件,因此我認爲我沒有正確執行。我開始使用fread(),但我想我可能需要使用fseek(),但我不確定。如果有人能指出我的方向是正確的還是告訴我如果我做錯了什麼,我會很感激。在C中一次讀取一個文件16字節0

代碼:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int main(int argc, char *argv[]) 
{ 
    FILE *fp; 

    int i, j; 

    unsigned char buffer[17]; 

    fp = fopen(argv[1], "r"); 

    while(!feof(fp)) 
    { 
     while(fread(buffer, 16, 1, fp) !=0) 
     { 

      for(i=0; i < 16; i++) 
      { 
       printf("%X ", buffer[i]); 
      } 

      for(j = 0; j < 16; j++) 
      { 
       if(isprint(buffer[j])) 
        printf("%s", buffer[j]); 
       else 
        printf("."); 
      } 

      printf("\n"); 
     } 
    } 

    fclose(fp); 

    return 0; 
} 

預期輸出:

0001: 40 4F 28 37 0B B8 FF 9D 81 5E 2E 73 B5 CC 6A 70 @O(7.....^.s..jp 
0010: 0F 30 9C 6E 7E F7 53 E0 C1 5E 9A 38 C5 02 F2 33 .0.n .S..^.8...3 

編輯:固定的問題與建議。以文本模式打開文件而不是二進制文件。將讀取模式更改爲"rb",代碼現在正常工作。

回答

3

您需要以二進制模式打開文件,在文本模式下對文件使用fseek/ftell會導致不穩定的值。

所以打開該文件

fp = fopen(argv[1], "rb"); 

也是很好的做法是要經常檢查,如果通過檢查返回值,在這種情況下if (fp != NULL) ...

而不是讀16字節塊成功函數讀取1個字節16倍,否則,如果該文件的長度不是16你錯過了最後一個字節

if (fp != NULL) 
{ 
    int read = 0; 
    while((read = fread(buffer, 1, 16, fp)) > 0) 
    { 
    for(i=0; i < read; i++) 
    { 
    ... 
    } 
    fclose(fp); 
} 

督察無需爲外均勻可分

printf("%s", buffer[j]); 

你沒有使用正確的格式說明,緩衝[J]是一個字符,而不是一個字符串,因此寫

printf("%c", buffer[j]); 

編輯:如果你是不是在一些嵌入式環境下最小的堆棧讀取一次16個字節並不那麼有效,您可以像讀取2k或更大的大小一樣讀取更快。

+0

啊,好吧,我看到我出錯的地方。修正它現在打印正確。現在我要開始處理文件偏移量。你知道這是否會用'fseek()'或'fread()'來完成嗎? – bkedge 2014-10-16 20:07:55

+0

@ wh33lybrdy使用fseek在文件中定位。您可以根據第二個參數指定從開始或結束的偏移量,例如SEEK_END。如果你有更多的問題,最好發佈他們,而不是繼續編輯這個問題,因爲過了一段時間這個問題變得非常混亂。 – 2014-10-16 20:08:52

相關問題