3

Let's say that filesystem::current_path will return the path:

/tmp/1567519419.773012

But I want a trailing separator. If seems like all I should have to do would be:

filesystem::current_path() / filesystem::path()

This works on gcc giving me:

/tmp/1567519419.773012/

But on , while the filesystem::current_path also gives me the absolute path without a trailing seperator, dividing by filesystem::path() has no effect. The resulting path is still the absolute path without a trailing separator.

I'd like code that is cross platform compatible, and I'd like to avoid having to detect whether the current path already has a trailing separator.

Is there anything available to me?

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • Don't Capitalise almost Every Word In The Title. And isn't it trivial to write a function to do this? –  Sep 03 '19 at 14:15
  • What do `current_path()` and `path()` return? – Mark Ransom Sep 03 '19 at 14:19
  • 1
    @MarkRansom Not sure what you mean... Those are standard library functions: https://en.cppreference.com/w/cpp/filesystem/current_path – Max Langhof Sep 03 '19 at 14:26
  • @MarkRansom `current_path` returns an absolute path to my working directory without the trailing separator. `path` is nothing, just blank. – Jonathan Mee Sep 03 '19 at 14:28
  • 1
    You say it doesn't work on Visual Studio, so you should explain what happens on Visual Studio. – Brian Bi Sep 03 '19 at 14:30
  • @Brian Thanks for the tip. I see that was unclear. Does my edit seem clear to you? – Jonathan Mee Sep 03 '19 at 14:37
  • Yes that's much better – Brian Bi Sep 03 '19 at 14:38
  • 2
    I believe this is even the intended behavior. The examples on cppreference look like this: [std::filesystem::path::operator /=](https://en.cppreference.com/w/cpp/filesystem/path/append) _path("C:") / ""; // the result is "C:" (appends, without separator)_ although, I personally think that "C:" and "C:/" is a difference but this has to mean nothing... ;-) – Scheff's Cat Sep 03 '19 at 14:40
  • @Scheff Wow... that's disappointing. I guess I need to make a function to do this to get uniform behavior? Thanks for pointing that out. – Jonathan Mee Sep 03 '19 at 14:43
  • What are you trying to do exactly? – Lightness Races in Orbit Sep 03 '19 at 15:05
  • @LightnessRacesinOrbit Ensure there is a trailing separator on the path. This path will be passed, as a string to another library, so I need to ensure there is exactly one trailing separator on the path. – Jonathan Mee Sep 03 '19 at 15:09
  • @JonathanMee Then create the string and just normalise it standard string manipulation tools? It's trivial. I don't see the need to try to do this at the conceptual path level, unless there's something you're not telling us. – Lightness Races in Orbit Sep 03 '19 at 15:12
  • @LightnessRacesinOrbit Yeah that's what I'm thinking I have to do. I'm saddened to see that what I need to do this is only available in gcc's implementation of filesystem :( When I wrote this I assumed that the dependency was a Visual Studio bug. – Jonathan Mee Sep 03 '19 at 15:27
  • The flaw is in confusing conceptual paths, with strings that abide by your string requirements – Lightness Races in Orbit Sep 03 '19 at 15:47
  • 1
    @JonathanMee So you're saying you want the [lexically normal](https://en.cppreference.com/w/cpp/filesystem/path/lexically_normal) version of the path [plus](https://en.cppreference.com/w/cpp/filesystem/path/concat) a [preferred separator](https://en.cppreference.com/w/cpp/filesystem/path#Member_constants)? – JaMiT Sep 03 '19 at 15:50
  • @JaMiT Yeah. It sounds like, `filesystem::current_path() / filesystem::path()`'s behavior is platform defined. I want the gcc behavior. But to get that in a platform independent way it looks like I am responsible for writing a helper function. – Jonathan Mee Sep 03 '19 at 15:54
  • @MaxLanghof I was aware that those were standard functions, just hoping that knowing the exact strings returned would provide some insight. – Mark Ransom Sep 03 '19 at 15:56
  • 1
    @LightnessRacesinOrbit since the path separator changes depending on what OS you're using, this doesn't seem like an unreasonable request. – Mark Ransom Sep 03 '19 at 15:58
  • 1
    @MarkRansom Append `std::filesystem::path::preferred_separator`? – Lightness Races in Orbit Sep 03 '19 at 16:26

1 Answers1

3

I'm not familiar enough with filesystem to know which compiler is correct (possibly both are, if there is implementation-defined behavior involved). However, the following should work on all platforms that correctly implement filesystem:

#include <iostream>
#include <filesystem>

int main() {
    auto foo = std::filesystem::current_path();
    foo += foo.preferred_separator; // A static data member of std::filesystem::path

    // The lexically normal form eliminates doubled separators
    std::cout << foo.lexically_normal().string() << '\n';
}
JaMiT
  • 14,422
  • 4
  • 15
  • 31
  • This does exactly what I need. I can even one line it. I just can't get it to work on Visual Studio 2017 cause `lexically_normal` isn't supported :/ I'll still accept, but if you knew of another way to force normalization. It would be appreciated. – Jonathan Mee Sep 03 '19 at 17:43