ICoffeeConsumer
ICoffeeConsumer

Reputation: 912

Why can't I copy executables like this?

Using C++'s <fstream>, it's pretty easy to copy a text file:

#include <fstream>

int main() {
    std::ifstream file("file.txt");
    std::ofstream new_file("new_file.txt");

    std::string contents;
    // Store file contents in string:
    std::getline(file, contents);
    new_file << contents; // Write contents to file

    return 0;
}

But when you do the same for an executable file, the output executable doesn't actually work. Maybe std::string doesn't support the encoding?

I was hoping that I could do something like the following, but the file object is a pointer and I'm not able to dereference it (running the following code creates new_file.exe which actually just contains the memory address of something):

std::ifstream file("file.exe");
std::ofstream new_file("new_file.exe");

new_file << file;

I would like to know how to do this because I think it would be essential in a LAN file-sharing application. I'm sure there are higher level APIs for sending files with sockets, but I want to know how such APIs actually work.

Can I extract, store, and write a file bit-by-bit, so there's no discrepancy between the input and output file? Thanks for your help, it's much appreciated.

Upvotes: 1

Views: 1588

Answers (2)

Jesse Good
Jesse Good

Reputation: 52365

Not sure why ildjarn made it a comment, but to make it an answer (if he posts an answer, I will delete this). Basically, you need to use unformatted reading and writing. getline formats the data.

int main()
{
    std::ifstream in("file.exe", std::ios::binary);
    std::ofstream out("new_file.exe", std::ios::binary);

    out << in.rdbuf();
}

Technically, operator<< is for formatted data, except when use it like the above.

Upvotes: 7

paddy
paddy

Reputation: 63471

In very basic terms:

using namespace std;

int main() {
    ifstream file("file.txt", ios::in | ios::binary );
    ofstream new_file("new_file.txt", ios::out | ios::binary);

    char c;
    while( file.get(c) ) new_file.put(c);

    return 0;
}

Although, you'd be better off making a char buffer and using ifstream::read / ofstream::write to read and write chunks at a time.

Upvotes: 2

Related Questions