Home > Software design >  How to make copies of the executable itself in C ?
How to make copies of the executable itself in C ?

Time:09-11

I want to make copies of the exe file itself multiple times.

I tried the following code:

#include <fstream>
#include <string>

int main() {
    std::ifstream from("main.exe", std::ios::binary);
    auto buf { from.rdbuf() };

    for(int x { 0 }; x <= 10;   x) {
        std::string name { "main"   std::to_string(x)   ".exe" };

        std::ofstream out(name, std::ios::binary);
        out << buf;
        out.close();
    }

    from.close();
    return 0;
}

But it doesn't work as I expected (It does not copy the executable repeatedly. See the size column in the following screenshot):

The executables not completely copied

Please help me to solve this problem.
Thanks.

CodePudding user response:

Reading from the input file stream buffer consumes the data. You need to reset the stream to the start after copying the file:

...

for (int x{ 0 }; x <= 10;   x) {
    std::string name{ "main"   std::to_string(x)   ".exe" };

    std::ofstream out(name, std::ios::binary);
    out << buf;
    out.close();
    from.seekg(0, std::ios::beg); // need to go back to the start here
}

...

You could simply use the std::filesystem standard library functionality for this though:


int main() {
    std::filesystem::path input("main.exe");

    for (int x{ 0 }; x <= 10;   x) {
        std::filesystem::path outfile("main"   std::to_string(x)   ".exe");

        std::filesystem::copy_file(input, outfile, std::filesystem::copy_options::overwrite_existing);
    }

    return 0;
}

CodePudding user response:

After you read all of the contents from the input buffer during your first iteration, your input buffer is empty. Thus, your subsequent iterations will also render empty copies. I suggest moving the from buffer initialization inside the loop like so:

#include <fstream>
#include <string>

int main() {

    for (int x{ 0 }; x <= 10;   x) {
        std::ifstream from("main.exe", std::ios::binary);
        auto buf{ from.rdbuf() };
        std::string name{ "main"   std::to_string(x)   ".exe" };

        std::ofstream out(name, std::ios::binary);
        out << buf;
        out.close();
        from.close();
    }

    
    return 0;
}

Here's what you should get: enter image description here

CodePudding user response:

It seems like in the other answers the data will be read from the file multiple times (once per save).

It will more efficient to read it once into memory, then save as many times as needed from memory:

#include <string>
#include <vector>
#include <fstream>

int main() {

    // Read the entire main.exe file into memory:
    const std::string inFilename{ "main.exe" };
    std::ifstream inFile{ inFilename, std::ios_base::binary };
    std::vector<char> inFileData{ std::istreambuf_iterator<char>(inFile), std::istreambuf_iterator<char>() };
    inFile.close();

    // Save it as many times as needed:
    for (int x{ 0 }; x <= 10;   x) 
    {
        std::string name{ "main"   std::to_string(x)   ".exe" };
        std::ofstream outFile{ name, std::ios::binary };
        outFile.write(inFileData.data(), inFileData.size());
        outFile.close();
    }
}

CodePudding user response:

The first copy is done perfectly. My best guess is that the input buffer is empty afterwards, so all consecutive copies are empty.

  • Related