2015-04-06 68 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