2013-09-27 46 views
0

我編寫了一個函數來從文件的指定位置讀取給定數量的字節。當從main調用時,這會按預期工作。但是當它從一個其他函數被調用,而這個函數又被main調用時,它會讀取一些額外的垃圾字符(其中一些是不可打印的)。fread |的怪異行爲一個函數在從main調用時會有不同的表現,在從其他函數調用時會有不同的表現

請解釋發生了什麼,以及如何防止它。代碼和相應的輸出如下:

編輯:最終目標是計算這個數據的散列,創建一個數據包(數據+哈希),並通過TCP套接字發送到另一個節點網絡。

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

char * read_from_file(char * filename, int offset, int n_bytes) 
{ 
    printf("Inside read function\n"); 
    printf("offset: %d\n",offset); 
    printf("n_bytes: %d\n",n_bytes); 
    char * bfr; 
    FILE * f_ptr; 
    int count; 

    f_ptr = fopen (filename,"r"); 
    if(f_ptr==NULL) 
    { 
     printf("File not found\n"); 
     exit(1); 
    } 
    //Set the offset position 
    fseek(f_ptr, offset , SEEK_SET); 
    //memory aloocation 
    bfr = malloc (sizeof(char)*n_bytes); 
    if (bfr == NULL) 
    { 
     printf("Memory allocation problem\n"); 
     exit (2); 
    } 
    count = fread(bfr,1,n_bytes,f_ptr); 
    printf("no. of characters read from file: %d\n",count); 
    printf("string read: %s\n", bfr); 
    printf("Length of string read: %zd\n",strlen(bfr)); 

    if (count != n_bytes) 
    { 
     printf("Error in reading the file"); 
     exit(1); 
    } 
    // Close the file 
    fclose (f_ptr); 
    printf("Exiting read function\n\n"); 
    return bfr; 
} 

int send_file()//nc_args_t * nc_args) 
{ 
    printf("Inside send_file\n"); 
    char * data; 
    data = malloc (10); 
    data = read_from_file("alphabet.txt", 0, 10); 
    printf("Length of data: %d\n",strlen(data)); 
    printf("Data Read: %s\n", data); 

} 

int main() 
{ 
    char * data; 
    data = read_from_file("alphabet.txt", 0, 10); 
    printf("Length of data: %zd\n",strlen(data)); 
    printf("Data Read: %s\n", data); 
    printf("\nCalling send_file\n"); 
    send_file(); 
} 

輸出

Inside read function 
offset: 0 
n_bytes: 10 
no. of characters read from file: 10 
string read: ABCDEFGHIJ 
Length of string read: 10 
Exiting read function 

Length of data: 10 
Data Read: ABCDEFGHIJ 

Calling send_file 
Inside send_file 
Inside read function 
offset: 0 
n_bytes: 10 
no. of characters read from file: 10 
string read: ABCDEFGHIJLsE 
Length of string read: 14 
Exiting read function 

Length of data: 14 
Data Read: ABCDEFGHIJLsE 

回答

1

你不分配的字符串的空終止額外的字節,你不是低保終止存在。您必須爲緩衝區分配n_bytes + 1並確保最終字節爲零。

+0

其實,我想計算的散列這個,創建一個數據包並通過TCP套接字發送給其他網絡。我仍然需要'\ 0'嗎? – shahensha

+0

我不知道你想發送什麼,需要一個以空字符結尾的字符串或一個給定長度的字符數組。請查閱您要發送的TCP數據包的規範。 –

2

通話

count = fread(bfr,1,n_bytes,f_ptr); 

bfr後不一定是一個字符串,因爲它可能不是空終止,因此使用printf("string read: %s\n", bfr);不能打印的內容,或者使用strlen得到它的長度。您需要打印的每個字符在一個循環:

感謝

for (int i = 0; i < n_bytes; i++) 
    printf("%c", bfr[i]); 
printf("\n"); 

編輯@Jonathan Leffer的評論,這看起來方式更好:

printf("%.*s\n", count, bfr); 
+0

如果'bfr'不是'\ 0'終止的,其他字節可能不是不可打印的,這樣'%c'以外的格式是有保證的?或者如果只有文本跳過循環並使用'printf(「%。* s \ n」,n_bytes,bfr);'? – chux

+0

@chux你說得對,打印十六進制會更好,假設數據是任意的二進制數據。這取決於OP想要的內容,根據示例,數據是可打印的字符。 –

+0

您可以使用'printf(「%。* s \ n」,count,bfr);'假設讀取的數據不包含任何零(空)字節。 –

相關問題