Function can't read entire executable file.

Hello everybody!
I am writing a program which compresses files into .zip files.
Here's my problem: Whenever I want to compress an executable file, my readFile function does not read the entire file. When I extract the .exe I get a very tiny and incomplete file.

Here's the function I use to read files:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
std::string miniz_wrapper::readFile(FILE* f, int MAX_FILEBUFFER)
//MAX_FILEBUFFER has a default value of 65536
{
	char* tmp;
	std::string tmp_s;
	int count = 0;

	while (!feof(f))
	{
		tmp = (char*)malloc(MAX_FILEBUFFER + 1);
		fgets(tmp, MAX_FILEBUFFER, f);
		tmp[MAX_FILEBUFFER] = '\0';
		tmp_s.append(tmp);
		free(tmp);
		++count;
	}
	printf("%d lines read\n", count);
	
	return tmp_s;
}


Prior to reading, every file is opened using fopen with the mode "rb".

I appreciate every comment :)
C++ is not C. Why not using C++?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <string>
#include <fstream>
#include <iostream> //won't use this
std::string readfile(const std::string file)
{
    std::ifstream file_;
    file_.open(file.c_str());
    std::string ret;
    std::string ch;
    while(std::getline(file_, ch))
    {
        if(!ch.empty()) ret += ch + "\n";
    }
    return ret;
}

int main()
{
    std::cout << readfile("main.cpp"); //kinda quine
}
@iQChange
Your code modifies the input. OP's requirements forbid that.

@PrydeRage
You are using the wrong functions to do this. You should be looking at
http://www.cplusplus.com/reference/cstdio/fread/

You are also looping on EOF -- which is I hope you understand is typically the wrong thing to do -- even though it is correct in your code as it is.

There is no need for the MAX_FILEBUFFER argument, since you will be storing everything in a string to return. Better memory management is to allocate all the memory you need (the filesize) at the front, then just read into the string. (Which, despite older standard documentation, is safe in every extant implementation.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
std::string miniz_wrapper::readFile(FILE* f, int MAX_FILEBUFFER)
{
	// given: f is opened with mode "rb"

	std::string result;
	long int size;

	// Get the size of the necessary block of memory
	fseek(f, 0, SEEK_END);
	size = ftell(f);
	if (size < 0)
		throw error or return "" or something;
	rewind(f);

	// Load the file data into the string
	result.resize(size);
	if (fread((void*)result.data(), 1, size, f) != (size_t)size)
		throw error or return "" or something;

	return result;
}

I did not test the code. (I wrote it off the top of my head. JSYK.)

Hope this helps.
Sadly, neither code works. Both of your methods write exactly 2 characters.
However, @Duoas when I print the size after rewind(f); it prints 720 kb, which is the correct file size.
1
2
3
4
5
6
7
std::string read_binary( const std::string& file_name )
{
     std::ifstream file( file_name, std::ios_base::binary ) ;

     using iterator = std::istreambuf_iterator<char> ;
     return { iterator(file), iterator() } ;
}

http://coliru.stacked-crooked.com/a/e13d69f12bc297d8
Dang! I forgot about that there streambuf_iterator! Nice!
(Unfortunately, it violates the OP's API requirement over a *FILE.)

@OP. I don't know what you mean by "neither code works" and "both of your methods write exactly 2 characters".

The code I wrote above doesn't write any characters at all. It reads them. If you have modified it, you might want to consider what your modifications have done to invalidate the code I wrote.

Because I just tested it and it works fine.
Haha, Douas, I have been thinking on the same: What? My function is writting?
Last edited on
Topic archived. No new replies allowed.