Что такое кросс-платформенный способ получения текущего каталога?
Мне нужен кросс-платформенный способ получить текущий рабочий каталог (да, getcwd делает то, что я хочу). Я думал, что это может сделать трюк:
#ifdef _WIN32
#include <direct.h>
#define getcwd _getcwd // stupid MSFT "deprecation" warning
#elif
#include <unistd.h>
#endif
#include <string>
#include <iostream>
using namespace std;
int main()
{
string s_cwd(getcwd(NULL,0));
cout << "CWD is: " << s_cwd << endl;
}
Я получил это сообщение:
Не должно быть утечек памяти, и он должен работать и на Mac, правильно?
ОБНОВЛЕНИЕ: я боюсь, что что-то здесь все еще не так (я пытаюсь избежать создания массива char с определенной длиной, так как нет подходящего способа получить приличную длину для getcwd):
char* a_cwd = getcwd(NULL,0);
string s_cwd(a_cwd);
free(a_cwd); // or delete a_cwd?
Ответы
Ответ 1
Вы не можете вызвать getcwd
с помощью NULL-буфера. Согласно Opengroup:
Если buf является нулевым указателем, поведение getcwd() не указано.
Кроме того, getcwd может возвращать NULL, который может разбить конструктор строк.
Вам нужно изменить это на что-то вроде:
char buffer[SIZE];
char *answer = getcwd(buffer, sizeof(buffer));
string s_cwd;
if (answer)
{
s_cwd = answer;
}
Ответ 2
Если вам не нужно включать, используйте повысить файловую систему для удобной работы межплатформенной файловой системы.
boost::filesystem::path full_path( boost::filesystem::current_path() );
Вот example.
EDIT: как отметил Рой Дантон в комментариях, файловая система стала частью ISO С++ в С++ 17, поэтому boost больше не требуется:
std::filesystem::current_path();
Ответ 3
Вызов getcwd с указателем NULL - это реализация определена. Часто это распределение для вас с помощью malloc (в этом случае ваш код имеет утечку памяти). Тем не менее, он не гарантированно работает вообще. Поэтому вы должны выделить свой собственный буфер.
char *cwd_buffer = malloc(sizeof(char) * max_path_len);
char *cwd_result = getcwd(cwd_buffer, max_path_len);
В Open Group есть пример, показывающий, как получить максимальную длину пути от _PC_PATH_MAX. Вы можете использовать MAX_PATH в Windows. См. этот вопрос для предостережений к этому номеру на обеих платформах.