Replacing a specific part of a parent_path of std::filesystem path?

How would I go about replacing a specific part of the parent_path using std::filesystem?

Originally I was converting an entry to a path then to a string like so:
entry.path().string()
Then using string modifiers to rename a specific part then using ifstream or ofstream to open the file using that string.

However, I was told it'd be better to use filesystem instead of string modifiers. But after looking into it for a while, I don't see how that is possible.

My program will recursively go through a directory and convert every entry to a path variable one at a time.
- I want it to replace "InputFiles" with "OutputFiles" in each path name.
- Then I want it to check if the entire path exists and if not, create the directories.

For example, I could have the file path:
/mnt/c/Users/Tom/Desktop/PROGRAMMING RELATED/langs/C++/git-projects/json_file_simplifier/json_file_simplifier/InputFiles/firstDirectTest/2ndDirectTest/3rdDirectTest/myfile.txt

And I want my code to:

1. Search the file path for "InputFiles" and if found then replace it with "OutputFiles"
2. Determine if the new file path already exists:
/mnt/c/Users/Tom/Desktop/PROGRAMMING RELATED/langs/C++/git-projects/json_file_simplifier/json_file_simplifier/OutputFiles/firstDirectTest/2ndDirectTest/3rdDirectTest/myfile.txt

3. If it does not already exist, create the directories (not the text file).

Edit:
If needed, my old code can be seen here - https://pastebin.com/7YKECYZX
* Specifically the iterateInDirectory() and writeJsonAsTxt() functions.
My new code is honestly such a mess at this point in time that it's not worth looking at.

Edit 2: Here are some useful links -
https://en.cppreference.com/w/cpp/filesystem/path
https://en.cppreference.com/w/cpp/filesystem/path/parent_path
Last edited on
I must say, using a regex from the <regex> to easily swap out part of the path-as-string with a new string seemed a fairly simple way to go:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <string>
#include <filesystem>
#include <regex>

int main()
{
  std::filesystem::path pathOne("/mnt/c/Users/Tom/Desktop/PROGRAMMING RELATED/langs/C++/git-projects/json_file_simplifier/json_file_simplifier/InputFiles/firstDirectTest/2ndDirectTest/3rdDirectTest/myfile.txt");
  std::filesystem::path pathTwo(std::regex_replace(pathOne.string(), std::regex("InputFiles"), "OutputFiles"));

  // Output new path to show the change has been made
  std::cout << pathTwo.string();
}


Granted, you said you don't want to do this, but it seems fairly easy and simple.

Last edited on
@Repeater
Thanks for your quick reply!

I am open to using such a method, but I do wonder whether converting it to a string temporarily would negatively impact performance or resources cost, rather than just using std::filesystem (if there is a method with filesystem).

I'll be iterating through roughly 800-1500 file paths at the moment and I do notice a pause in my program before it completes. Which is fine yes, but it's always one's goal to increase performance. :)

Edit:
I'm guessing your way would be faster than mine because it uses an included library which has probably been optimized more than my code, right?

My code example:
1
2
3
        std::string outputEntryStr = entry->path().string();
        int inputPosInEntry = outputEntryStr.find("InputFiles");
        outputEntryStr.replace(outputEntryStr.begin()+inputPosInEntry, outputEntryStr.begin()+inputPosInEntry+2, "Out");


And my more recent code example (only difference is no entry->path() part, now is a dot):
1
2
3
        std::string outputEntryStr = entry.path().string();
        int inputPosInEntry = outputEntryStr.find("InputFiles");
        outputEntryStr.replace(outputEntryStr.begin()+inputPosInEntry, outputEntryStr.begin()+inputPosInEntry+2, "Out");


This code will:
- Convert path to string
- Determine where the starting position of "Input" is in the string
- Replace the "In" with "Out" in the string at that position.

Edit 2:
- I tried implementing it into my code. If nothing else, it makes the code shorter and easier to read. :) And yeah I'm guessing it's faster.

Post solved. Thanks. :)
Last edited on
"notice a pause" At what point exactly are you noticing lag? Are you reading files over a loop or something of that nature?
A simple regex is going to be insignificant compared to doing file reading/writing (assuming the regex truly is simple and not one of those ones that blow up in complexity).

If you're worried about performance, measure. Try method (A), measure, then try method (B), measure. If you see a performance dip in one of them, then that's a good place to start looking. If both methods are too slow for your liking, try to figure out specifically which part of the processing is the bottleneck.

If you're truly worried about performance, don't just guess. Measure.
Last edited on
Topic archived. No new replies allowed.