Есть платформа-агностик и файловой системы-агностик способ получить полный путь к директории, откуда запущена программа на C/с++? Не путать с текущего рабочего каталога. (Пожалуйста, Дон'т рекомендовать библиотекам, если только они не're стандартный, как clib или STL.)
(Если там's нет платформы/файловой системы-агностик способ, пожелания, которые работают в Windows и Linux для конкретных файловых систем приветствуются тоже.)
Здесь's код, чтобы получить полный путь к приложению, выполнив:
Окна:
int bytes = GetModuleFileName(NULL, pBuf, len);
if(bytes == 0)
return -1;
else
return bytes;
Линукс:
char szTmp[32];
sprintf(szTmp, "/proc/%d/exe", getpid());
int bytes = MIN(readlink(szTmp, pBuf, len), len - 1);
if(bytes >= 0)
pBuf[bytes] = '\0';
return bytes;
Если вы забрали текущего каталога, когда программа запускается в первый раз, то вы эффективно иметь каталог вашей программы был запущен. Сохранить значение в переменной и использовать их позже в вашей программе. Это отличается от каталог, содержащий текущий исполняемый файл программы. Это'т всегда один и тот же каталог; если кто-то запускает программу из командной строки, то программа *запустить из командной строки's в текущей рабочей директории, хотя файл программы живет в другом месте.
функция getcwd является функцией POSIX и поддерживает из коробки на всех уступчивых POSIX платформах. Вам не придется делать ничего особенного (кроме включая право заголовков запустите.H на UNIX и прямые.ч на Windows).
Так как вы создаете программу на C, это будет связь с по умолчанию среды выполнения C библиотеки времени, который связан со всеми процессами в системе (специально созданных исключений избегать) и она будет включать эту функцию по умолчанию. ЭЛТ никогда не считал внешнюю библиотеку, потому что обеспечивает основной стандарт совместимый интерфейс для операционной системы.
В Windows функция функция getcwd является устаревшим в пользу методов _getcwd. Я думаю, вы могли бы использовать его в этом моде.
#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);
Это из форум cplusplus
На Windows:
#include <string>
#include <windows.h>
std::string getexepath()
{
char result[ MAX_PATH ];
return std::string( result, GetModuleFileName( NULL, result, MAX_PATH ) );
}
На 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 );
}
На 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 );
}
Если вы хотите стандартный способ без библиотеки: нет. Вся концепция каталога не входит в стандарт.
Если вы согласны, что некоторые (портативный) зависимость от почти стандартных Либ-это хорошо: используйте импульс'библиотека файловая система с и задайте для работы функции initial_path().
ИМХО, что's как близко, как вы можете сделать, с хорошей кармой (Boost-это устоявшееся высокое качество набор библиотек)
Файловая система ТС сейчас стандартный ( и поддерживается с помощью GCC 5.3+ и лязг 3.9+ ), так что вы можете использовать current_path()
функцию от него:
std::string path = std::experimental::filesystem::current_path();
В GCC (5.3+), чтобы включить файловой системы, вы должны использовать:
#include <experimental/filesystem>
и связать свой код с-lstdc++флаг ДФ`.
Если вы хотите использовать файловую систему с помощью Visual Studio, то читать это.
Я знаю, что это очень поздно в день, чтобы бросить ответ на это, но я обнаружил, что ни один из ответов были полезны для меня как мое собственное решение. Очень простой способ, чтобы получить путь от ухо до папки bin, как это:
int main(int argc, char* argv[])
{
std::string argv_str(argv[0]);
std::string base = argv_str.substr(0, argv_str.find_last_of("/"));
}
Теперь вы можете просто использовать это как основание для ваших относительный путь. Так, например, у меня есть такая структура каталогов:
main
----> test
----> src
----> bin
и я хочу, чтобы скомпилировать мой исходный код в bin и написать отчет для проверки, я могу просто добавить эту строку в мой код.
std::string pathToWrite = base + "/../test/test.log";
Я пробовал такой подход на Linux, используя полный путь, псевдоним и т. д. и это работает просто отлично.
Примечание:
Если вы находитесь на Windows, вы должны использовать '\' в качестве разделителя файл не '/'. Вам придется бежать это тоже к примеру:
std::string base = argv[0].substr(0, argv[0].find_last_of("\\"));
Я думаю, что это должно работать, но не'т испытана, поэтому комментарии будут оценены, если он работает или исправить, если не.
Нет, там'ы не стандартным способом. Я считаю, что C и C++ стандарты не'т даже рассмотреть вопрос о существовании каталогов (или другой файловой системы организации).
На окна GetModuleFileName() возвращает полный путь к исполняемому файлу процесса, когда hModule параметр нуль. Я могу'т помочь с Linux.
<удар>также вы должны уточнить, является ли вы хотите, чтобы текущий каталог или каталог, что программа Image/находится исполняемый файл. Как он стоит, ваш вопрос немного неоднозначный на данный момент.</удара>
Может быть, объединить текущий рабочий каталог с argv[0]? Я'м не уверен, если это будет работать в Windows, но он работает в Linux.
Например:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char **argv) {
char the_path[256];
getcwd(the_path, 255);
strcat(the_path, "/");
strcat(the_path, argv[0]);
printf("%s\n", the_path);
return 0;
}
При запуске, он выдает:
Джереми@Джереми стола:~/рабочий стол$ ./тест /домой/Джереми/рабочий стол/./тест
В Windows Самый простой способ заключается в использовании функции _get_pgmptr
в stdlib.ч
, чтобы получить указатель на строку, которая представляет собой абсолютный путь к исполняемому файлу, включая имя программы.
char* path;
_get_pgmptr(&path);
printf(path); // Example output: C:/Projects/Hello/World.exe
Вы не можете использовать argv[0] для этой цели, как правило, она содержит полный путь к исполняемому файлу, но не nessesarily - процесс может быть создан с произвольного значения в поле.
Также заметьте, текущий каталог и каталог с исполняемым две разные вещи, поэтому функция getcwd() выиграл'т вам помочь.
На Windows использовать GetModuleFileName(), в Linux чтение из /dev/прок/procID/.. файлы.
Для системы Windows в консоли можно использовать команду(реж
). И консоль дает вам информацию о каталоге и т. д. Читал про команду реж
в КМД
. Но для UNIX-подобных систем, я не'т знаю... если эта команда выполняется, команда на чтение Баш. LS
не отображать каталог...
Пример:
int main()
{
system("dir");
system("pause"); //this wait for Enter-key-press;
return 0;
}
Просто запоздало грузить,...
стандартного решения не существует, потому что языки не зависят от файловой системы, так как уже сказал, концепция каталога файловой системы, основанные выходит за рамки Си / Си++.
кроме того, требуется не текущий каталог, а каталог, на котором запущена программа, которая должна учитывать, каким образом программа должна где - то есть она породила в качестве нового процесса с помощью вилки и т. д. Чтобы получить каталог программы под управлением в, в качестве решения продемонстрировали, что вам необходимо получить эту информацию от процесса управления структуры операционной системы, который является единственным авторитетом в этом вопросе. Таким образом, по определению, своего ОС, конкретное решение.
#include <windows.h>
using namespace std;
// The directory path returned by native GetCurrentDirectory() no end backslash
string getCurrentDirectoryOnWindows()
{
const unsigned long maxDir = 260;
char currentDir[maxDir];
GetCurrentDirectory(maxDir, currentDir);
return string(currentDir);
}
Команду bash в Linux что имя_программы сообщит путь к программе.
Даже если можно было бы выдавать что команду в вашей программе и прямой выход к tmp-файлов и программы впоследствии говорится, что файл tmp, она не будет сообщать вам, если что программа выполняется. Это только говорит вам, где программы, это имя находится.
Что требуется, чтобы получить свой идентификатор процесса, и, чтобы разобрать путь к имени
В моей программе я хочу знать, если программа была выполнен из пользователей's директории bin или из другой в пути или из /usr/Бен. /usr/Бен будет содержать поддерживаемая версия. Мне кажется, что в Linux есть одно решение, которое является портативным.
Для относительных путей, здесь's то, что я сделал. Я знаю возраст этого вопроса, я просто хочу внести проще ответить, что работает в большинстве случаев:
Скажем, у вас есть путь такой:
"path/to/file/folder"
Почему-то, Линукс-причине исполняемые работы в затмения хорошо с этим. Однако, в Windows становится очень запутанной, если дается этот путь, чтобы работать с!
Как указано выше, существует несколько способов, чтобы получить текущий путь к исполняемому файлу, но самый простой способ я найти автор в большинстве случаев добавление их к передней части вашего пути:
"./path/to/file/folder"
Просто добавив, что "./&я должен сделать вы сортируются! :) Тогда вы можете начать загрузку из любого каталога, так как он с самого исполняемого.
Редактировать: этот выиграл'т работать, если вы попытаетесь запустить исполняемый файл из кода::блоки, если что's в среду разработки используется, так как по каким-то причинам, код::блоки не'т загрузки вещи... :Д
EDIT2: некоторые новые вещи, я обнаружил, что если указать статический путь в ваш код (предполагая, например.данные-это то, что вам нужно для загрузки):
"resources/Example.data"
Если вы запустите ваше приложение из текущего каталога (или в Windows, создайте ярлык, и установить рабочее реж в приложение реж), то она будет работать так. Имейте это в виду при отладке проблем, связанных с отсутствием ресурсов/пути к файлам. (Особенно в Ides, что поставили неправильную рабочего каталога при запуске сборки EXE-файл из IDE)
Увеличить файловую систему'ы работы функции initial_path()
ведет себя как в POSIX'ы функция getcwd (), а не то, что вы хотите сама по себе, но с добавлением
argv[0] в` к любому из них должен сделать это.
Вы можете заметить, что результат не всегда хорош ... вы можете сделать такие вещи, как в/Foo/бар/../../баз/на.из
или `в/Foo/бар/баз/на."выйти", но я считаю, что это всегда приводит в правильный путь, имена которых исполняемого файла (обратите внимание, что Слэша в пути рухнула в один).
Я уже написал решение с помощью параметре envp(третий аргумент основной ()
, который работал на Linux, но ничего'т, кажется, работоспособные в Windows, поэтому я'м по сути предложив то же решение, что кто-то еще раньше, но с дополнительными разъяснениями, почему это на самом деле правильно, даже если результаты будут не очень.
Как Минок нутые, нет такой функции, указанные стандартный ini файл C или C++ стандарт. Это считается чисто ОС-спецификой и указано в стандарте POSIX, например.
Thorsten79 дал хорошее предложение, это импульс.Библиотека файловой системы. Однако, это может быть неудобно в случае, если вы не'т хотим, чтобы любой ссылке-зависимости времени в двоичной форме для вашей программы.
Хорошая альтернатива, я бы порекомендовал-это коллекция из 100% только заголовков STLSoft библиотеки C++ Мэтью Уилсон (Автор нужно читать книги о c++). Есть переносные фасад PlatformSTL дает доступ к системе-определенным API: WinSTL для Windows и UnixSTL на Unix, так это портативное решение. Вся система конкретных элементов указываются с использованием признаков и политики, так это расширяемой платформы. Есть библиотека файловой системы, конечно.
Работает с Начиная с C++11, использование экспериментальной файловой системы, и C++14-в C++17, а также через официальный файловой системы.
приложения.ч:
#pragma once
//
// https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros
//
#ifdef __cpp_lib_filesystem
#include <filesystem>
#else
#include <experimental/filesystem>
namespace std {
namespace filesystem = experimental::filesystem;
}
#endif
std::filesystem::path getexepath();
application.cpp:
#include "application.h"
#ifdef _WIN32
#include <windows.h> //GetModuleFileNameW
#else
#include <limits.h>
#include <unistd.h> //readlink
#endif
std::filesystem::path getexepath()
{
#ifdef _WIN32
wchar_t path[MAX_PATH] = { 0 };
GetModuleFileNameW(NULL, path, MAX_PATH);
return path;
#else
char result[PATH_MAX];
ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
return std::string(result, (count > 0) ? count : 0);
#endif
}