1

I wrote a small program to get the magic number from an .au file and print it to console, but every time I try, instead of getting the intended .snd, I get .snd$ instead.

I'm not sure why this is happening, considering that I'm only reading in 4 bytes, which is what the magic number is comprised of. So, where is the extra character coming from?

#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

Delfino
  • 967
  • 4
  • 21
  • 46
  • 2
    you don't have a null terminator on your `m` array, so printf() will keep spitting out bytes until it encounters one. – Marc B Apr 06 '15 at 18:23

2 Answers2

2

You're printing it as though it were a string, which in C, means that it's NUL-terminated. Change your code like this and it will work as you expect:

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

Also, you should be aware that scanf is a dangerous function. Use a command line argument instead.

Edward
  • 6,964
  • 2
  • 29
  • 55
  • 1
    @Delfino: Updated my answer to provide a link answering your question. In brief, it's bad because it can lead to buffer overflow and is thus a security and robustness problem. – Edward Apr 06 '15 at 18:30
1

The problem is not how you are reading. The problem is that your variable is only 4 chars length, and it needs a null character to indicate the end.

printf with %s will print the content of the variable until reach a null character, until that it can print garbage if your variable is not correctly ended. To fix you can have a bigger variable and set the [4] char with null.

How the new code should look like:

#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;
}
dfranca
  • 5,156
  • 2
  • 32
  • 60
  • Not quite right. `NUL` is a character = `'\0'`, but `NULL` in C is a pointer, so you've swapped one problem for another -- buffer overrun. – Edward Apr 06 '15 at 18:26
  • Not exactly, nullptr in C++11 is a pointer, NULL can be defined both as a macro to 0 or to ( (void*) 0) according to the standard. But anyway I edited the implementation to use '\0' – dfranca Apr 06 '15 at 18:31