-1

I wanted to write a program in C++ where it copied all the files in a folder and pasted them into another folder. For now, I managed only with a single file.

#include <iostream>
#include <windows.h>

using namespace std;

int main (int argc, char *argv[])
{
    CopyFile ("C:\\Program Files (x86)\\WinRAR\\Rar.txt","C:\\Users\\mypc\\Desktop\\don't touch\\project\\prova", TRUE);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    `CopyFile()` only copies one file. To copy multiple files, you need to loop over all files, and call `CopyFile()` for each one. Look up the functions `FindFirstFile()` and `FindNextFile()` for options to implement that loop, as well as `GetFileAttributes()` and `SetFileAttributes()` if you need to copy file properties (e.g. protections). Bear in mind that, directories contain directories - to copy a directory, it is necessary to loop over all files in the directory - recursively. – Peter Feb 02 '19 at 23:59
  • Alternatively, like at `SHFileOperation()`, then you don't need a loop, you can use wildcards instead. – Remy Lebeau Feb 03 '19 at 01:33
  • Check out [`std::filesystem::copy`](https://en.cppreference.com/w/cpp/filesystem/copy), which *should* work on any system, not just Windows. – DevSolar Feb 05 '19 at 14:34

1 Answers1

0

As one of the comments suggest, CopyFile only copies one file at a time. One option is to loop through the directory and copy the files. Using filesystem (which can be read about here ), allows us to recursively open directories, copy that directories files and the directories directories and on and on until everything has been copied. Also, I did not check the arguments being input by the user, so don't forget that if its important to you.

# include <string>
# include <filesystem> 

using namespace std;
namespace fs = std::experimental::filesystem;
//namespace fs = std::filesystem; // my version of vs does not support this so used experimental

void rmvPath(string &, string &);

int main(int argc, char **argv)
{
    /* verify input here*/

    string startingDir = argv[1]; // argv[1] is from dir
    string endDir = argv[2]; // argv[2] is to dir

    // create dir if doesn't exist
    fs::path dir = endDir;
    fs::create_directory(dir);

    // loop through directory
    for (auto& p : fs::recursive_directory_iterator(startingDir))
    {
        // convert path to string
        fs::path path = p.path();
        string pathString = path.string();

        // remove starting dir from path
        rmvPath(startingDir, pathString);

        // copy file
        fs::path newPath = endDir + pathString;
        fs::path oldPath = startingDir + pathString;


        try {
            // create file
            fs::copy_file(oldPath, newPath, fs::copy_options::overwrite_existing);
        }
        catch (fs::filesystem_error& e) {
            // create dir
            fs::create_directory(newPath);
        }
    }

    return 0;
}


void rmvPath(string &startingPath, string &fullPath) 
{
    // look for starting path in the fullpath
    int index = fullPath.find(startingPath);

    if (index != string::npos)
    {
        fullPath = fullPath.erase(0, startingPath.length());
    }
}