views:

208

answers:

4

I am writing a cross-platform compatible function in C++ that creates directories based on input filenames. I need to know if the machine is Linux or windows and use the appropriate forward or back slash. For the following code below, if the machine is Linux then isLinux = true. How do I determine the OS?

bool isLinux;
std::string slash;
std::string directoryName;

if isLinux
   slash = "/";
else
   slash = "\\";
end

boost::filesystem::create_directory (full_path.native_directory_string() + slash + directoryName); 
+10  A: 

Generally speaking, you'd have do do this with conditional compilation.

That said, if you're using boost::filesystem you should be using the portable generic path format so that you can forget about things like this.

Billy ONeal
I am not sure if I understand the example"OpenVMS: "SYS1::DISK1:[JANE.TYLER.HARRY]" is treated as a native pathname with a system name, drive name, and three directory filenames, rather than a portable pathname with one filename.-- Windows: "c:\\jane\\tyler\\harry" is treated as a native pathname with a drive letter, root-directory, and three filenames, rather than a portable pathname with one filename.if full_path.native_directory_string() = c:\\toys and I want to create folder "blocks" then how would I write that using portable generic path format?
Elpezmuerto
@Elpez: You can't use `native_directory_string`... It's not going to output in the right format. I can say that your final directory path should be something like C:/toys/blocks .
Billy ONeal
A: 

One of the most used methods to do this is with a pre-processor directive. The link is for C but they're used the same way in C++. Fair warning, each compiler & OS can have their own set of directives.

nathan
+6  A: 

Use:

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
static const std::string slash="\\";
#else
static const std::string slash="/";
#endif

BTW, you can still safely use this slash "/" on Windows as windows understands this perfectly. So just sticking with "/" slash would solve problems for all OSes even like OpenVMS where path is foo:[bar.bee]test.ext can be represented as /foo/bar/bee/test.ext.

Artyom
There are a few Win32 functions that do not like the incorrect Win32 directory separator character "/". But if you use Win32 functions, then you probably already know that you are targeting Windows.
Andreas Rejbrand
@Andreas, which Win32 functions have trouble with the "/" ?
Tomas
By "few" I really mean "few"... :) I think that some of these are sensitive: http://msdn.microsoft.com/en-us/library/bb773559(VS.85).aspx In addition, there is an explicit warning here: http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx. Nevertheless, the main thing I have against the forward slash is that it hurts in my eyes when I see one of those in a Microsoft Windows path...
Andreas Rejbrand
I didn't try, but the shell functions, being used by explorer with user-entered paths, should be quite abuse-resistant (although it may just sanitize all its input before passing to them).
Matteo Italia
A: 

Look into http://en.wikipedia.org/wiki/Uname

If you are using g++ as your compiler/GNU then you could try the code below. POSIX compliant environments support this:

#include <stdio.h>
#include <sys/utsname.h>
#include <stdlib.h>

int main()
{
    struct utsname sysinfo;
    if(uname(&sysinfo)) exit(9);
    printf("os name: %s\n", sysinfo.sysname);
    return 0;
}
Fanatic23
Windows does not have anything in the `<sys` directory. That's POSIX only.
Billy ONeal
@Billy Please do read http://en.wikipedia.org/wiki/Uname before a downvote. I mentioned g++, and GNU supports this. I have compiled the code on g++/CYGWIN.
Fanatic23
@Billy ONeal - when using MinGW or cygwin, Windows can possess it.
doc
@Arpan: I did read the article. Cygwin is not windows, it is an emulation layer built on top of windows.
Billy ONeal