Sign in to follow this  
Shadowflare

fread() problem

Recommended Posts

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!

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
#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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this