Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my simple C program displaying garbage to stdout?

Tags:

c

file-io

Consider the following simple C program that read a file into a buffer and displays that buffer to the console:

#include<stdio.h>

main()
{
  FILE *file;
    char *buffer;
    unsigned long fileLen;
    //Open file
    file = fopen("HelloWorld.txt", "rb");
    if (!file)
    {
        fprintf(stderr, "Unable to open file %s", "HelloWorld.txt");
        return;
    }
    //Get file length
    fseek(file, 0, SEEK_END);
    fileLen=ftell(file);
    fseek(file, 0, SEEK_SET);
    //Allocate memory
    buffer=(char *)malloc(fileLen+1);
    if (!buffer)
    {
        fprintf(stderr, "Memory error!");
        fclose(file);
        return;
    }
    //Read file contents into buffer
    fread(buffer, fileLen, 1, file);
    //Send buffer contents to stdout
    printf("%s\n",buffer);    
    fclose(file);
}

The file it will read simply contains:

Hello World!

The output is:

Hello World!²²²²▌▌▌▌▌▌▌↔☺

It has been a while since I did anything significant in C/C++, but normally I would assume the buffer was being allocated larger than necessary, but this does not appear to be the case.

fileLen ends up being 12, which is accurate.

I am thinking now that I must just be displaying the buffer wrong, but I am not sure what I am doing wrong.

Can anyone clue me in to what I am doing wrong?

like image 414
GEOCHET Avatar asked Nov 03 '08 22:11

GEOCHET


People also ask

What does stdout mean in C?

stdout stands for standard output stream and it is a stream which is available to your program by the operating system itself. It is already available to your program from the beginning together with stdin and stderr .

What will be the output of the C code?

Output is dependent on the compiler. For 32 bit compiler it would be fffffffe and for 16 bit it would be fffe.


3 Answers

You need to NUL-terminate your string. Add

buffer[fileLen] = 0;

before printing it.

like image 113
JesperE Avatar answered Oct 24 '22 06:10

JesperE


JesperE's approach will work, but you may be interested to know that there's an alternate way of handling this.

You can always print a string of known length, even when there's no NUL-terminator, by providing the length to printf as the precision for the string field:

printf("%.*s\n", fileLen, buffer);

This allows you print the string without modifying the buffer.

like image 28
George Eadon Avatar answered Oct 24 '22 06:10

George Eadon


JesperE is correct regarding the nul-termination issue in your example, I'll just add that if you are processing text files it would be better to use fgets() or something similar as this will properly handle newline sequences across different platforms and will always nul-terminate the string for you. If you are really working with binary data then you don't want to use printf() to output the data as the printf functions expect strings and a nul byte in the data will cause truncation of the output.

like image 8
Robert Gamble Avatar answered Oct 24 '22 06:10

Robert Gamble