2014-09-22 45 views
0
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define SIZE 255 

void hexDump (char *desc, void *addr, int len) { 
    int i; 
    unsigned char buffLine[17]; 
    unsigned char *pc = (unsigned char*)addr; 


    if (desc != NULL){ 

     printf ("%s:\n", desc); 

    } 


    for (i = 0; i < len; i++) { 


     if ((i % 16) == 0) { 

      if (i != 0) 

       printf (" %s\n", buffLine); 
      // if (buffLine[i]== '\0') break; 

      if (pc[i] == 0x00) exit(0); 

      // Prints the ADDRESS 
      printf (" %07x ", i); 
     } 

     // Prints the HEXCODES that represent each chars. 
     printf ("%02x", pc[i]); 
     if ((i % 2) == 1) 
      printf (" "); 



     if ((pc[i] < 0x20) || (pc[i] > 0x7e)){ 
      buffLine[i % 16] = '.'; 
     } 

     else{ 

      buffLine[i % 16] = pc[i]; 

     }  


     buffLine[(i % 16) + 1] = '\0'; //Clears the next array buffLine 


    } 



    while ((i % 16) != 0) { 
     printf (" "); 
     i++; 
    } 


    printf (" %s\n", buffLine); 
} 

//---------------------------------------------- 

int main() 
    { 
      FILE *ptr_file; 
      char buff[SIZE]; 

      ptr_file =fopen("input.txt","r"); 
      if (!ptr_file){ 
      printf("returning 1"); 
       return 1; 
      } 

      memset(buff, '\0', sizeof(buff)); 
      fgets(buff,SIZE, ptr_file); 
      hexDump ("buff", &buff, sizeof (buff)); 

     fclose(ptr_file); 

      return 0; 
    } 
    //*/ 

對不起,這個我是新的C,所以它有點凌亂,現在,我已經刪除的部分,使臨時代碼,等等 所以反正這是通過讀取字符從input.txt輸出並通過在右側打印十六進制表示和Acii表示形式輸出。因爲,打印一個「」字符(點/句號,即十六進制值2E):形成非打印字符字節hexdump都計劃

0003540: 0504 0675 6e73 6967 6e65 6420 6368 6172 ...unsigned char 
0003550: 0008 0107 0000 0131 0675 6e73 6967 6e65 .......1.unsigne 

,但我的程序不打印任何超出了‘新線’文本。 例如: 在我input.txt中,我有:

This is line 1 so this will be longer than usual 
line 2 is this 
this is the last line 

閱讀我的程序後,它只輸出是這樣的:

0000000 5468 6973 2069 7320 6c69 6e65 2031 2073 This is line 1 s 
    0000010 6f20 7468 6973 2077 696c 6c20 6265 206c o this will be l 
    0000020 6f6e 6765 7220 7468 616e 2075 7375 616c onger than usual 
    0000030 0a00 0000 0000 0000 0000 0000 0000 0000 ................ 

但由於某些原因,它不會打印和十六進制第二行,第三行....

+0

您或者需要在循環中調用'fgets',一次讀取一行或使用'fread'來讀取固定大小的塊。 – 2014-09-22 08:18:02

回答

1

您應該使用fread()來讀取文件,並將其放入循環(直到它返回0),以便它讀取整個文件。如果你在Windows上,也一定要用「rb」(二進制模式)打開文件,而在Unix上它應該沒有關係。

最後一個建議是使用isascii()或其姐妹功能之一,而不是手動檢查「適印性」。見http://linux.die.net/man/3/isalnum

1

您只需撥打fgets一次。 fgets從文件中讀取一行,並在耗盡SIZE字符限制,當它遇到文件結尾或遇到換行符時停止。所以這種行爲是可以預料的。

數據的長度通常會小於char限制,但是您會打印所有的SIZE字符,這會給您零。

如果您想要處理所有行,則應在循環中調用fgets,並在返回NULL時將其分解。您還應該通過strlen(buf)作爲長度參數而不是sizeof(buf),這會給您通常過長的SIZE

十六進制自卸車的目的是使任何文件的數據可見。您使用fgetschar,這應該用於文本文件。 (例如,我不確定fgets在遇到空字節時會做什麼)。

因此,最好使用字節,即unsigned char,並使用fread以塊爲單位讀取它們。如果您將塊大小設置爲16的倍數,這將幫助您設置輸出的格式。所以:

for (;;) { 
    unsigned char buf[SIZE]; 
    size_t n = fread(buf, 1, SIZE, f); 

    if (n > 0) dump(buf, n); 
    if (n < SIZE) break; 
} 
1

你需要使用「RB」而不是「R」來打開二進制模式的文件

然後用FREAD()從文件,無論是從它或讀出存儲塊讀整個文件。