2010-07-09 4 views
17

J'écris une fonction compatible multi-plateforme en C++ qui crée des répertoires basés sur des noms de fichiers en entrée. J'ai besoin de savoir si la machine est Linux ou Windows et utiliser le slash avant ou arrière approprié. Pour le code suivant ci-dessous, si la machine est Linux, alors isLinux = true. Comment puis-je déterminer le système d'exploitation?Déterminer si Linux ou Windows en C++

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); 
+7

Si vous n'allez pas montrer le chemin à l'utilisateur, vous pouvez le garder simple et utiliser simplement une barre oblique. Windows comprend les deux. (Si vous * prévoyez * de le montrer, vous devriez probablement utiliser des barres obliques inverses sous Windows - cela semble plus cohérent avec le système d'exploitation.) –

Répondre

32

Utilisation:

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

BTW, vous pouvez toujours utiliser en toute sécurité cette barre oblique "/" sous Windows que Windows comprend parfaitement. Donc, coller simplement avec "/" barre oblique résoudrait des problèmes pour tous les systèmes d'exploitation même comme OpenVMS où le chemin foo:[bar.bee]test.ext peut être représenté comme /foo/bar/bee/test.ext.

+5

Il existe quelques fonctions Win32 qui n'aiment pas le caractère séparateur de répertoire Win32 incorrect "/". Mais si vous utilisez des fonctions Win32, alors vous savez probablement déjà que vous ciblez Windows. –

+0

@Andreas, quelles fonctions Win32 ont des problèmes avec le "/"? – Tomas

+4

Par "peu" je veux vraiment dire "peu" ... :) Je pense que certains d'entre eux sont sensibles: http://msdn.microsoft.com/en-us/library/bb773559(VS.85).aspx En outre, il existe un avertissement explicite ici: http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx. Néanmoins, la principale chose que j'ai contre la barre oblique est que ça fait mal dans mes yeux quand j'en vois un dans un chemin Microsoft Windows ... –

13

De manière générale, vous auriez fait cela avec une compilation conditionnelle. Cela dit, si vous utilisez boost::filesystem, vous devriez utiliser le portable generic path format afin que vous puissiez oublier des choses comme ça.

+0

Je ne suis pas sûr de comprendre l'exemple " OpenVMS:" SYS1 :: DISK1: [JANE.TYLER.HARRY] "est traité comme un chemin d'accès natif avec un nom de système, un nom de lecteur et trois noms de fichiers de répertoires, plutôt qu'un chemin d'accès portable avec un nom de fichier - Windows:" c: \\ jane \\ tyler \\ harry "est traité comme un chemin d'accès natif avec une lettre de lecteur, un répertoire racine et trois noms de fichiers, plutôt qu'un nom de chemin d'accès portable avec un nom de fichier si full_path.native_directory_string() = c: \\ jouets et je veux créer des dossiers "blocs" alors comment pourrais-je écrire cela en utilisant le format de chemin générique portable? – Elpezmuerto

+0

@Elpez: Vous ne pouvez pas utiliser 'native_directory_string' ... Il ne va pas sortir dans le bon format. Je peux dire que votre chemin de répertoire final devrait être quelque chose comme C:/toys/blocks. –

0

L'une des méthodes les plus utilisées pour ce faire est avec un pre-processor directive. Le lien est pour C mais ils sont utilisés de la même manière en C++. Avertissement juste, chaque compilateur & OS peut avoir son propre ensemble de directives.

1

Regardez dans http://en.wikipedia.org/wiki/Uname

Si vous utilisez g ++ comme compilateur/GNU, vous pouvez alors essayer le code ci-dessous. environnements compatibles POSIX soutiennent ceci:

#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; 
} 
+6

Windows n'a rien dans le répertoire '

+0

@Billy S'il vous plaît lisez http://en.wikipedia.org/wiki/Uname avant un downvote. J'ai mentionné g ++, et GNU le supporte. J'ai compilé le code sur g ++/CYGWIN. – Fanatic23

+0

@Billy ONeal - lorsque vous utilisez MinGW ou cygwin, Windows peut le posséder. – doc

4

Par défaut, Visual Studio #define s _WIN32 dans les paramètres du projet de préprocesseur.

, vous pouvez utiliser

// _WIN32 = we're in windows 
#ifdef _WIN32 
// Windows 
#else 
// Not windows 
#endif 
0

predef.sourceforge.net est une collection complète de tous les types de MACROs qui identifient les compilateurs/systèmes d'exploitation et plus. (lien direct vers le sous-site du système d'exploitation)

Questions connexes