I would like to write a function :
inline char separator()
{
/* SOMETHING */
}
that returns the file separator of the system in standard C/C++/C++11 ? (I mean slash or backslash depending on the system). Is there a way to achieve this ?
I'm not sure how to do it other than by checking ifdefs
inline char separator() { #ifdef _WIN32 return '\\'; #else return '/'; #endif }
or (as suggested by PaperBirdMaster)
const char kPathSeparator = #ifdef _WIN32 '\\'; #else '/'; #endif
If your compiler offers c++17 capabilities, then you can use std::filesystem::path::preferred_separator
which yields the preferred separator char depending on your platform. For example, on Windows this would usually be \
whereas on Linux you'd get /
.
See this for more information.
This question is really hinting at a much nastier problem.
If you simply care about UNIX vs. Winodws and you only care about directories and files, then what you've already seen will (mostly) work, but the more generic issue of splicing a path name into its components is a much uglier problem. Depending on the platform, a path may include one or more of:
While there are 3rd party libraries (like various CPAN Perl modules, Boost, and others) for this, and every OS includes system functions for this, there's nothing built-in to C for this and the C++ standard only gained this functionality (by incorporating the Boost module) in 2017.
Some examples of what such a function may need to deal with are:
There are many others as well.
It is worth noting that the C++17 filesystem library does not cover all of these possibilities. The std::filesystem::path
consists of an optional root-name (a volume identifier), an optional root-directory (to identify absolute paths), and a sequence of filenames separated by directory separators. This covers everything likely to be valid on UNIX platforms and the majority of use-cases for other platforms, but is not comprehensive. For example, it does not have any support for sub-streams (relying on the OS to somehow map them onto a file name - which is done by Mac OS X, but not classic MacOS). It also does not include support for file version numbers.
See also Wikipedia's entry on Path and the C++17 std::filesystem::path class
http://en.cppreference.com/w/cpp/filesystem
I recommend you look at what you want to do with the directory separator (extract the base-name, break a path into a list of directories, etc.) and write a function to do that. If you're using C++17 (and you are certain your code won't be compiled by a pre-17 C++ compiler) then you can (probably) use standard C++ library code to write a portable implementation of this function. If not, that function will need to use platform-specific #ifdef
s for each platform you will be supporting, using a #error
if none of the conditions are met, to force you to to add conditions for unexpected platforms.
Or use a 3rd party library (like Boost) that includes functions for all of this, if that is acceptable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With