C ++ argv указатель пути - PullRequest
       12

C ++ argv указатель пути

0 голосов
/ 09 апреля 2010

В интерпретаторе для моих языков программирования я должен правильно обрабатывать детали в случае вызова функции import. Затем мне нужно проверить, находится ли такой файл в папке /libs (находится там же, где и мой исполняемый файл!), И если он не существует, я должен проверить в каталоге текущего скрипта.

  • Как получить точный путь к каталогу, в котором находится исполняемый файл из argv?
  • Каков наилучший способ удалить файл в конце пути, например:

    C:/a/b/c/file.exe должно стать C:/a/b/c/

Ответы [ 6 ]

2 голосов
/ 09 апреля 2010

Непереносимый способ в Linux (и, возможно, в другом * nix) заключается в использовании readlink в / proc / self / exe, если argv [0] не содержит весь путь.

2 голосов
/ 09 апреля 2010
  1. Не существует гарантированного способа сделать это. Вы можете попробовать поискать в argv[0], но имеет ли полный путь или просто имя двоичного файла, зависит от платформы и от того, как был вызван ваш процесс.
  2. Вы можете использовать strrchr, чтобы найти последний слеш и заменить символ после него на '\0'

Пример кода:

// Duplicate the string so as not to trash the original
// You can skip this if you don't mind modifying the original data
// and the originald is writeable (i.e. no literal strings)
char *path = strdup(...);

char *last_slash = strrchr(path, '/');
if (last_slash)
{
#if PRESERVE_LAST_SLASH
    *(last_slash + 1) = '\0';
#else
    *last_slash = '\0';
#endif
}
1 голос
/ 09 апреля 2010

Если в вашей среде есть эквивалент PWD, вы можете просто добавить к нему / $ argv [0].

Это может дать вам то, чего вы не ожидаете, например /foo1/foo2/../foo3/, но это нормально. Это допустимый путь, и его можно использовать в глобальном формате.

0 голосов
/ 09 апреля 2010

Для Windows (непереносной) используйте :: GetModuleFileName () и :: PathRemoveFileSpec ():

TCHAR sPath[MAX_PATH] = {0};
if(::GetModuleFileName(NULL, sPath, MAX_PATH))
    ::PathRemoveFileSpec(sPath))
// sPath is the executable path if the module is an exe
0 голосов
/ 09 апреля 2010

Не оптимально, но отлично работает:

int main(int argc, char **argv) {
    using namespace std;
    char buffer[MAXPATHLEN];
    realpath(argv[0], buffer);
    string fullpath = buffer;
    fullpath = string(fullpath, 0, fullpath.rfind("/"));
    cout << fullpath << endl;
}

Для относительного пути я использую realpath (), который специфичен для Unix / Linux. Для окон вы можете использовать GetModuleFileName (NULL, buffer, MAXPATHLEN), и, конечно, разделитель не тот.

0 голосов
/ 09 апреля 2010

Сканирование назад от конца строки для первого '/' символа.

...