2017-01-26 32 views
-1

我試圖從圖像文件中使用C讀取十六進制值。在Linux中,此代碼工作正常,但對於Windows,它只讀取第一個334字節,我不明白爲什麼。讀取圖像中的十六進制值C

的代碼讀取該文件是:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/stat.h>  
void readHexFile(char* path) { 
     FILE *fp; 

     if ((fp = fopen (path, "r")) != NULL) { 
      struct stat st; 
      stat(path, &st);     

      int i; 
      int ch; 
      for (i = 0; i < st.st_size; i++) { 
       ch = fgetc(fp);    
       printf("%x ", ch); 
      } 

      fclose(fp); 
     } 
     else { 
      return NULL; 
     } 
} 

st.st_size來自<sys/stat.h>包,包含正確的值(字節大小,圖像文件)

此圖片顯示什麼我程序輸出以及它正在讀取的文件的實際二進制內容:

enter image description here 正如您在17的順序後看到的那樣,18,19也有十六進制值,但我的程序反覆打印ffffffff

+0

有被注意到待觀察。看[問]並提供[mcve]。並且不要發佈文字的圖像! – Olaf

+0

是的,但圖像顯示正確的十六進制值 – Davide

+1

*'st.st_size來自包'* - 什麼包? – Wolf

回答

1

我覺得你的循環應該是這樣的:

int ch; 
while (!feof(fp)) { 
    ch = fgetc(fp); 
    printf("%x ", ch); 
} 

它完全是我不清楚你爲什麼在這裏使用st.st_size

+0

如果我使用while循環它打印直到0x19但文件越來越長 – Davide

+0

那麼,你的問題顯然是[使用文本模式](http://stackoverflow.com/a/41876316/2932052)。但是不使用'foef'背後的原因是什麼? – Wolf

+0

是的。我用st.st_size來顯示你錯誤的十六進制。是的,現在我已經在使用EOF – Davide

5

您在文本模式打開的文件和二進制不是。不同的平臺行爲可能不同。

在這種情況下,微軟的Windows決定,這純文本文件在Ctrl+Z0x1A)第一次出現結束,並返回EOF所有fgetc之後。

明確規定要打開的文件爲二進制:

fp = fopen ("yourfile", "rb"); 

和問題消失。

+0

Woow!謝謝。你救了我的命。現在工作正常! – Davide

+0

太棒了,但是如果'0x1A'的意思是'Ctrl + Z',爲什麼你把它放在圓括號裏? – Wolf

1

在Windows中,字符0x1A(按Ctrl + Z)用於文本模式的EOF字符;見this question

如果你從像JPEG二進制文件閱讀,你應該先打開該文件作爲二進制(fopen模式"rb"),然後fread到預先分配的緩衝區這樣做,它的大小,你會確定與ftell與在該文件的末尾的文件指針:

size_t i, len; 
char *buffer = NULL; 
fp = fopen(argv[1], "rb"); 
if(!fp) 
    // handle error 

fseek(fp, 0, SEEK_END); 
len = ftell(fp); 
rewind(fp); 

buffer = malloc(len + 1); 
if(!buffer) 
    // handle error 

fread(buffer, 1, len, fp); 
for(i = 0; i < len; i++) 
{ 
    printf("%.2X ", buffer[i]); 
} 

free(buffer); 
buffer = NULL;