2015-04-06 67 views
1

我寫了一個小程序從.au文件中獲取魔術數字並將其打印到控制檯,但是每次嘗試時,我都會改爲10,而不是獲得預期的.snd從.au讀取魔術數字文件

我不知道爲什麼會發生這種情況,考慮到我只讀了4個字節,這就是幻數組成的部分。那麼,額外角色從哪裏來?

#include <stdio.H> 

int main() 
{ 
    FILE *fin; 
    int r; 
    char m[4], path[20]; 

    scanf("%s", path); 
    fin = fopen(path, "r"); 
    r = fread(&m, sizeof(char), 4, fin); 
    printf("magic number is %s\n", m); 

    return 0; 
} 

Output

+2

你沒有你的'M'陣列上的空終止,所以printf()函數將保持吐出字節,直到遇到一個。 –

回答

2

你打印出來,就好像是一個字符串,在C,意味着它是NUL結尾。更改您這樣的代碼,也將努力爲您想到:也

char m[5]; 
m[4] = '\0'; /* add terminating NUL */ 

,你應該知道,scanf is a dangerous function。改爲使用命令行參數。

+0

它爲什麼危險? – Delfino

+1

@Delfino:更新了我的答案,以提供回答您的問題的鏈接。簡而言之,這很糟糕,因爲它可能會導致緩衝區溢出,從而導致安全性和健壯性問題。 – Edward

1

問題不在於你如何閱讀。 問題是你的變量只有4個字符的長度,並且它需要一個空字符來表示結束。

帶有%s的printf將打印變量的內容直到達到空字符,直到它可以在變量未正確結束時打印垃圾。 要解決您可以有一個更大的變量,並設置爲空[4] char。

如何在新的代碼應該是這樣的:

#include <stdio.H> 

int main() 
{ 
    FILE *fin; 
    int r; 
    char m[5], path[20]; 

    scanf("%s", path); 
    /*Scanf can be dangerous because it can cause buffer overflow, 
    it means that you can fill your variable with more bytes than it supports, which can end up being used for buffer overflow attacks:      
    See more: http://en.wikipedia.org/wiki/Buffer_overflow */ 
    fin = fopen(path, "r"); 
    r = fread(&m, sizeof(char), 4, fin); 
    m[4] = '\0'; 

    printf("magic number is %s\n", m); 

    return 0; 
} 
+0

不完全正確。 'NUL'是一個字符=''\ 0'',但C中的'NULL'是一個指針,所以你已經把一個問題換成另一個 - 緩衝區溢出。 – Edward

+0

不完全一樣,C++ 11中的nullptr是一個指針,根據標準,NULL可以被定義爲宏到0或((void *)0)。 但無論如何,我編輯的實施使用'\ 0' – danielfranca