291 Stimmen

Wie erhalte ich das Verzeichnis, in dem ein Programm ausgeführt wird?

Gibt es eine plattform- und dateisystemunabhängige Methode, um den vollständigen Pfad des Verzeichnisses zu ermitteln, in dem ein Programm mit C/C++ ausgeführt wird? Nicht zu verwechseln mit dem aktuellen Arbeitsverzeichnis. (Bitte schlagen Sie keine Bibliotheken vor, es sei denn, es sind Standardbibliotheken wie clib oder STL).

(Wenn es keine plattform- bzw. dateisystemunabhängige Methode gibt, sind Vorschläge, die unter Windows und Linux für bestimmte Dateisysteme funktionieren, ebenfalls willkommen).

4 Stimmen

Es sei denn, Sie können den Pfad zuverlässig aus argv[0] ist die Technik sehr betriebssystemabhängig.

2 Stimmen

Nur zur Klarstellung: Das "aktuelle Verzeichnis" oder "das Verzeichnis, in dem das Programm läuft" (in der Terminologie der Frage) ist das Verzeichnis, in dem sich die Image-Datei des Programms (~.exe-Datei) befindet, und das "aktuelle arbeiten directory' das Verzeichnis ist, das automatisch vervollständigt wird, wenn das Programm relative Pfade verwendet?

4 Stimmen

Wenn Sie #include <windows.h> setzt Windows automatisch eine char* zum ausführbaren Pfad in _pgmptr . Wenn Sie nur unter Windows arbeiten, brauchen Sie keine zusätzlichen Funktionen aufzurufen und keinen Müll anzunehmen.

200voto

Hier ist der Code, um den vollständigen Pfad zur ausführenden Anwendung zu erhalten:

Deklarationen von Variablen:

char pBuf[256];
size_t len = sizeof(pBuf); 

Fenster:

int bytes = GetModuleFileName(NULL, pBuf, len);
return bytes ? bytes : -1;

Linux:

int bytes = MIN(readlink("/proc/self/exe", pBuf, len), len - 1);
if(bytes >= 0)
    pBuf[bytes] = '\0';
return bytes;

172voto

computinglife Punkte 4227

Wenn Sie das aktuelle Verzeichnis beim ersten Start Ihres Programms abrufen, haben Sie effektiv das Verzeichnis, aus dem Ihr Programm gestartet wurde. Speichern Sie den Wert in einer Variablen und beziehen Sie sich später in Ihrem Programm darauf. Dies ist ein Unterschied zu das Verzeichnis, in dem sich die aktuelle ausführbare Programmdatei befindet . Es ist nicht unbedingt dasselbe Verzeichnis; wenn jemand das Programm von einer Eingabeaufforderung aus startet, wird das Programm laufen von das aktuelle Arbeitsverzeichnis der Eingabeaufforderung, auch wenn die Programmdatei woanders liegt.

getcwd ist eine POSIX-Funktion und wird von allen POSIX-kompatiblen Plattformen standardmäßig unterstützt. Sie müssen nichts Besonderes tun (abgesehen vom Einfügen der richtigen Header unistd.h unter Unix und direct.h unter Windows).

Da Sie ein C-Programm erstellen, wird es mit der Standard-C-Laufzeitbibliothek verknüpft, die von ALLEN Prozessen im System verknüpft wird (speziell erstellte Ausnahmen werden vermieden) und diese Funktion standardmäßig enthält. Die CRT wird nie als externe Bibliothek betrachtet, da sie die grundlegende standardkonforme Schnittstelle zum Betriebssystem bereitstellt.

Unter Windows wurde die Funktion getcwd zugunsten von _getcwd veraltet. Ich denke, Sie können es auf diese Weise verwenden.

#include <stdio.h>  /* defines FILENAME_MAX */
#ifdef WINDOWS
    #include <direct.h>
    #define GetCurrentDir _getcwd
#else
    #include <unistd.h>
    #define GetCurrentDir getcwd
 #endif

 char cCurrentPath[FILENAME_MAX];

 if (!GetCurrentDir(cCurrentPath, sizeof(cCurrentPath)))
     {
     return errno;
     }

cCurrentPath[sizeof(cCurrentPath) - 1] = '\0'; /* not really required */

printf ("The current working directory is %s", cCurrentPath);

47voto

Octopus Punkte 7586

Dies ist aus der cplusplus Forum

Unter Windows:

#include <string>
#include <windows.h>

std::string getexepath()
{
  char result[ MAX_PATH ];
  return std::string( result, GetModuleFileName( NULL, result, MAX_PATH ) );
}

Unter Linux:

#include <string>
#include <limits.h>
#include <unistd.h>

std::string getexepath()
{
  char result[ PATH_MAX ];
  ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX );
  return std::string( result, (count > 0) ? count : 0 );
}

Unter HP-UX:

#include <string>
#include <limits.h>
#define _PSTAT64
#include <sys/pstat.h>
#include <sys/types.h>
#include <unistd.h>

std::string getexepath()
{
  char result[ PATH_MAX ];
  struct pst_status ps;

  if (pstat_getproc( &ps, sizeof( ps ), 0, getpid() ) < 0)
    return std::string();

  if (pstat_getpathname( result, PATH_MAX, &ps.pst_fid_text ) < 0)
    return std::string();

  return std::string( result );
}

30voto

Thorsten79 Punkte 9872

Wenn Sie einen Standardweg ohne Bibliotheken wünschen: Nein. Das gesamte Konzept eines Verzeichnisses ist nicht in der Norm enthalten.

Wenn Sie zustimmen, dass eine (portable) Abhängigkeit von einer standardnahen Bibliothek in Ordnung ist: Verwenden Sie Boosts Dateisystem-Bibliothek und fragen Sie nach dem initial_path() .

IMHO ist das so gut wie möglich, mit gutem Karma (Boost ist ein gut etablierter, qualitativ hochwertiger Satz von Bibliotheken)

24voto

Sam Redway Punkte 6864

Ich weiß, dass es sehr spät ist, eine Antwort auf diese Frage zu geben, aber ich fand, dass keine der Antworten so nützlich für mich war wie meine eigene Lösung. Ein sehr einfacher Weg, um den Pfad von Ihrem CWD zu Ihrem bin-Ordner zu erhalten, ist wie folgt:

int main(int argc, char* argv[])
{
    std::string argv_str(argv[0]);
    std::string base = argv_str.substr(0, argv_str.find_last_of("/"));
}

Sie können dies nun einfach als Basis für Ihren relativen Pfad verwenden. So habe ich zum Beispiel diese Verzeichnisstruktur:

main
  ----> test
  ----> src
  ----> bin

und ich möchte meinen Quellcode nach bin kompilieren und ein Protokoll zum Testen schreiben, kann ich einfach diese Zeile zu meinem Code hinzufügen.

std::string pathToWrite = base + "/../test/test.log";

Ich habe diesen Ansatz unter Linux mit vollem Pfad, Alias usw. ausprobiert und er funktioniert einwandfrei.

HINWEIS:

Unter Windows sollten Sie ein "\" als Dateitrennzeichen verwenden, nicht "/". Sie müssen zum Beispiel auch dieses Zeichen entschlüsseln:

std::string base = argv[0].substr(0, argv[0].find_last_of("\\"));

Ich denke, dass dies funktionieren sollte, habe es aber nicht getestet, daher wäre ich für einen Kommentar dankbar, wenn es funktioniert, oder für eine Lösung, wenn nicht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X