fread() problem

Started by
2 comments, last by Last Attacker 18 years, 6 months ago
I am trying to read from a text file using fread(). However, when I read from the file, I get the contents of the file, but I also get random junk tagged onto the end. For example, lets say I have a file that contains the phrase "I like cheese!":

int main()
{
	FILE *fp;
	char *buffer;
	int filesize = 0;

	fp = fopen("cheese.txt", "r");

	fseek(fp, 0, SEEK_END);
	filesize = ftell(fp);   // get size of file
	rewind(fp);
	
	buffer = new char[filesize]; // allocate enough memory to hold the file

	fread((char *)buffer, 1, filesize, fp);

	fclose(fp);

	cout << buffer << endl;

        delete[] buffer;

	return 0;
}

Instead of printing "I like cheese!", it prints (in my case) "I like cheese!²²²²". I have been searching for a couple days for a solution to this, and I can't seem to find anyone who has had a similar problem. I thought perhaps it was allocating too much memory, and the end of the string was just random junk that was initially in my buffer, but no matter how many characters I read from the file, there is always extra characters stuck on the end. Can anyone help? Thanks!
Advertisement
Try allocating the memory as size of the file plus one. After reading the file in, make the last character '\0';

The system doesn't know where the end of the string is. fread is usually used for binary-mode operations, use something like fgets for text-mode.
There are actually two problems. The first is as Mercury pointed out, your char buffer is not null-terminated. The second is that since you are opening the file in text mode on some platforms (i.e. Windows) the size of the file as reported by fseek/ftell will not be the same as the number of characters read, since newlines are two characters in file and one character when read.

Why are you using C file functions in C++? Using fstreams is just as easy (arguably easier):
#include <fstream>#include <iostream>#include <iterator>#include <vector>int main(){	std::ifstream reader("cheese.txt");	// as a raw buffer	std::vector< char > raw_buffer((std::istreambuf_iterator< char >(reader)), std::istreambuf_iterator< char >());	reader.seekg(0, std::ios::beg);	// or as a string	std::string string_buffer((std::istreambuf_iterator< char >(reader)), std::istreambuf_iterator< char >());	// no null terminator required	std::cout << string_buffer << std::endl;}

Enigma
#include <stdio.h>#include <stdlib.h>int main(){	FILE *fp;		char *buffer;		int filesize;		fp = fopen("cheese.txt", "r");		fseek(fp, 0, SEEK_END);		filesize = ftell(fp);   // get size of file		fseek(fp, 0, SEEK_SET);		buffer = (char *) malloc(sizeof(char) * (filesize + 1)); // allocate enough memory to hold the file		fgets(buffer, filesize + 1, fp);		fclose(fp);		printf("%s\n", buffer);		free(buffer);		return 0;}


Quote:Original post by Enigma
Why are you using C file functions in C++? Using fstreams is just as easy (arguably easier)

Because we like to do for the heck of it.
"Take delight in the Lord and He will give you your heart's desires" - Psalm 37:4My Blog

This topic is closed to new replies.

Advertisement