2016-03-15 57 views
0

我正在嘗試使用C以二進制模式讀取文件,但它只在緩衝區中存儲了前43個字符。 我想以245字節的組讀取文件。它包含多字符字節和空字符。 這是文件的十六進制內容:爲什麼fread()沒有獲得預期的字節?

323031353037303735393036333130343739332032373231333732534e30323033323545533036303130340000000008557c0000000000693c0000000000000c0000000008557c0000000000693c0000000000000c0000000008557c0000000000693c0000000000000c00001c00001c00001c00000c00000c00000c00001c4d4e202020204942202020204f393920202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202039444b524d4144 

這是我的代碼:

char* to_hex(const char* strin) { 
    char * strout = malloc(2 * strlen(strin) + 1); 
    int x; 

    for (x = 0; x < strlen(strin);x++){ 
     sprintf(&strout[x+x],"%02x", (int)(*(unsigned char*)(&strin[x]))); 
    } 

    strout[2 * strlen(strin)]='\0' 
    return strout; 
} 

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

    FILE * pfinput = fopen("stack.bin", "rb"); 
    int lrec = 245; 
    char* sbuff = (char *)malloc((lrec + 1) * sizeof(char)); 

    if (pfinput != NULL) { 
     while (fread (sbuff, 1, lrec, pfinput) > 0){ 
      sbuff[lrec] = '\0'; 

      printf("len=%d hex=%s\n\n", strlen(sbuff), to_hex(sbuff)); 

     } 
    } 

    return 0; 
} 

它返回如下:

len=43 hex=323031353037303735393036333130343739332032373231333732534e3032303332354553303630313034 

爲什麼只讀取43個字符而不是245個?
你有其他選擇嗎?

+0

'它包含多字符字節和空字符'。 - 當然,你意識到strlen()是無用的嗎? –

回答

1

當您的字符串包含空字符時,不能使用strlen來可靠地計算字符數。您需要捕獲由fread讀取的字符數並使用它。

int nread = 0; 
while ((nread = fread (sbuff, 1, lrec, pfinput)) > 0)  

而不是

printf("len=%d hex=%s\n\n", strlen(sbuff), to_hex(sbuff)); 

您需要使用:

printf("len=%d hex=%s\n\n", nread, to_hex(sbuff)); 

您還需要通過nreadto_hex讓您能夠適當處理嵌入的空字符在那個功能。

char* to_hex(const char* strin, int nread) { 
    char * strout = malloc(2 * nread + 1); 
    int x; 

    for (x = 0; x < nread; x++){ 
     sprintf(&strout[x+x],"%02x", (int)(*(unsigned char*)(&strin[x]))); 
    } 

    strout[2 * nread]='\0'; 
    return strout; 
} 

之後,printf線必須是:

printf("len=%d hex=%s\n\n", nread, to_hex(sbuff, nread)); 

PS請注意,您在這裏泄漏內存。在調用printf時使用由to_hex分配的內存,但在此之後它不會被釋放。您可能想要在變量中捕獲該內存並釋放它。

char* hexstring = to_hex(sbuff, nread); 
printf("len=%d hex=%s\n\n", nread, hexstring); 
free(hexstring); 

此外,從main返回之前解除分配sbuff

free(sbuff); 

PS 2我將簡化線

 sprintf(&strout[x+x],"%02x", (int)(*(unsigned char*)(&strin[x]))); 

 int c = strin[x]; 
     sprintf(&strout[x+x],"%02x", c); 
+0

不,因爲你通過lrec並不意味着lrec字符被讀取。 –

+0

@MartinJames,好點。感謝您指出。 –

+0

謝謝@RSahu,一個問題:我還必須在每個循環中釋放(sbuff)'? – harrison4

0

'成功完成後,的fread()應返回成功讀取元件的數量',

fread()返回的vaue是唯一的方法確定已將多少個字節讀入緩衝區。在文件末尾,可能會讀取少於'lrec'的字符。

相關問題