tags:

views:

472

answers:

2

I have a certain boost::filesystem::path in hand and I'd like to append a string (or path) to it.

boost::filesystem::path p("c:\\dir");
p.append(".foo"); // should result in p pointing to c:\dir.foo

The only overload boost::filesystem::path has of append wants two InputIterators.

My solution so far is to do the following:

boost::filesystem::path p2(std::string(p.string()).append(".foo"));

Am I missing something?

+6  A: 

If it's really just the file name extension you want to change then you are probably better off writing:

p.replace_extension(".foo");

for most other file path operations you can use the operators /= and / allowing to concatenate parts of a name. For instance

boost::filesystem::path p("c:\\dir");
p /= "subdir";

will refer to c:\dir\subdir.

hkaiser
I'm working with Boost 1.35 so I don't have replace_extension yet. But even so I can't see how you thought it solves my problem. I want to **append** an "extension", not change it. I illustrated this in the question, suppose `path p("c:\\dir")`, now comes something that will append `abc` to `p`, which should result in `p` pointing to `c:\dirabc`. The operator `/` also can't help with my problem.
Zack
You should have mentioned you use Boost V1.35. There you have a global function replace_extension(path) doing the same as I described above. Additionally, replace_extension simply adds an extension if none is present already. If you want to modify parts of your path (for instance a directory part, say c:\\dir\\bla to c:\\dirfoo\\bla) you need to take the path apart, modify the parts of the path (which are just strings) with any string function you prefer and put them together afterwards. No way around this...
hkaiser
It doesn't add an extension if there isn't one (atleast not in 1.35). And if there is one it will replace it for me, which is **not** what I wanted. I simply want to **append**. Follow my suggested code on how I'm solving it now to see what I want.
Zack
+5  A: 
#include <iostream>
#include <string>
#include <boost/filesystem.hpp>


int main() {
  boost::filesystem::path p (__FILE__);

  std::string new_filename = p.leaf() + ".foo";
  p.remove_leaf() /= new_filename;
  std::cout << p << '\n';

  return 0;
}

Tested with 1.37, but leaf and remove_leaf are also documented in 1.35. You'll need to test whether the last component of p is a filename first, if it might not be.

Roger Pate
I'm not sure if this is better than what I currently do but I'll accept it anyway.
Zack
@Zack: It's very close to what you have. I had started with the 1.42 API, noticed your comments on the other answer about 1.35, and worked backwards to get this. However, this is easier to check, e.g. if p.leaf() == "." (because p == "/some/dir/").
Roger Pate