2011-04-19 96 views
1
#include <stdio.h> 

int main() { 
    unsigned char data[1]; 

    FILE *f = fopen("bill.jpg", "rb"); 

    while (!feof(f)) { 
    if (fread(data, 1, 1, f) > 0) { 
     printf("0x%02x\n", data[0]); 
    } 
    } 
    fclose(f); 
} 

這是對的嗎?我很擔心,因爲如果我使用hexdump查看文件,我會得到完全不同的輸出結果。二進制翻譯

+0

*完全*有點OTT,這是倒退(如下指出的) – wmercer 2011-04-19 22:02:33

回答

1

這應該正確打印十六進制文件的第一個字節。

檢查所使用的Hexdump實用程序的文檔,或告訴我們正在使用哪個平臺。一旦你明白它在做什麼,一些轉儲實用程序會在每行上以相反順序顯示字節,以使小端閱讀更直觀。

+0

是的,我沒有注意到這是倒退;你知道它爲什麼這麼做嗎?我可以想象這會讓人非常困惑。 – wmercer 2011-04-19 21:54:43

+1

在諸如80x86,VAX等小端機器上,它解釋了一系列字節,形成更大的數量,更直觀地閱讀。例如,值1000是0x3e8。 32位寄存器的值看起來像是'00 00 03 e8',但是當作爲32位值存儲在存儲器中時,最低有效字節位於最低地址處,因此按照標準遞增順序查看字節顯示出'e8 03 00 00'。反轉線的翻車機顯示了更自然的東西 - 用於多字節值。 – wallyk 2011-04-19 22:06:26

1

對不起,但沒有 - while (!feof(f))基本上總是錯誤的 - 它通常會讀取文件中的最後一個項目兩次。這裏有一個合理的使用十六進制翻斗車我幾年前寫的:

/* public domain by Jerry Coffin, tested with MS C 10.0 and BC 4.5 
*/ 
#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char **argv) { 
    unsigned long offset = 0; 
    FILE *input; 
    int bytes, i, j; 
    unsigned char buffer[16]; 
    char outbuffer[60]; 

    if (argc < 2) { 
     fprintf(stderr, "\nUsage: dump filename [filename...]"); 
     return EXIT_FAILURE; 
    } 

    for (j=1;j<argc; ++j) { 

     if (NULL ==(input=fopen(argv[j], "rb"))) 
      continue; 

     printf("\n%s:\n", argv[j]); 

     while (0 < (bytes=fread(buffer, 1, 16, input))) { 
      sprintf(outbuffer, "%8.8lx: ", offset+=16); 
      for (i=0;i<bytes;i++) { 
       sprintf(outbuffer+10+3*i, "%2.2X ",buffer[i]); 
       if (!isprint(buffer[i])) 
        buffer[i] = '.'; 
      } 
      printf("%-60s %*.*s\n", outbuffer, bytes, bytes, buffer); 
     } 
     fclose(input); 
    } 
    return 0; 
} 
+0

但是在這裏,'feof'基本上是多餘的,而不是遭受print-last-twice錯誤,因爲原始代碼檢查'fread'的返回值。 – 2011-04-19 07:22:18

+0

我不知道在eof的雙重閱讀,謝謝。 – wmercer 2011-04-19 22:01:57

+0

@Charles - 對,在這種情況下,這個bug是隱藏的(或至少是它的影響)。 – 2011-04-19 23:34:38