Подтвердить что ты не робот

Есть ли эквивалент С++ для getcwd?

Я вижу C getcwd через: человек 3 cwd

Я подозреваю, что у С++ есть аналогичный, который может вернуть мне std::string.

Если да, то что он называется, и где я могу найти его документацию?

Спасибо!

4b9b3361

Ответ 1

Хорошо, я отвечаю, хотя вы уже приняли ответ.

Еще лучше, чем обернуть вызов getcwd, будет использовать boost:: filesystem, где вы получаете объект path из функции current_path(). Библиотека файловой системы Boost позволяет вам делать много других полезных вещей, которые вам в противном случае понадобились бы для выполнения синтаксического анализа строк, например, проверки наличия файлов/каталогов, получения родительского пути, создания путей и т.д. Проверьте это, он также переносится, - что много кода синтаксического анализа строки, который в противном случае использовали бы, вероятно, не будет.

Обновление (2016): Файловая система была опубликована как техническая спецификация в 2015 году на основе Boost Filesystem v3. Это означает, что он может быть доступен уже с вашим компилятором (например, Visual Studio 2015). Для меня также кажется вероятным, что он станет частью будущего стандарта С++ (я бы предположил С++ 17, но я не знаю текущего состояния).

Обновление (2017): библиотека файловой системы была объединена с ISO С++ в С++ 17, для

std::filesystem::current_path();

Ответ 2

std::string конструктор может с уверенностью принять char* в качестве параметра. Удивительно, что есть и версия Windows.

Изменить: на самом деле это немного сложнее:

std::string get_working_path()
{
   char temp[MAXPATHLEN];
   return ( getcwd(temp, MAXPATHLEN) ? std::string( temp ) : std::string("") );
}

Память не является проблемой - temp - это буфер на основе стека, а конструктор std::string выполняет копирование. Возможно, вы могли бы сделать это за один раз, но я не думаю, что этот стандарт будет гарантировать это.

О распределении памяти через POSIX:

Функция getcwd() должна указывать абсолютный путь к текущему рабочему каталогу в массиве, на который указывает buf, и возвращать buf. Путь скопирован в массив не должен содержать компонентов, которые являются символьными ссылками. Аргумент размера - это размер в байтах массива символов, на который указывает аргумент buf. Если buf является нулевым указателем, поведение getcwd() не указано.

Ответ 3

Попробуйте переписать этот простой вызов C как С++:

std::string get_working_path()
{
    char temp [ PATH_MAX ];

    if ( getcwd(temp, PATH_MAX) != 0) 
        return std::string ( temp );

    int error = errno;

    switch ( error ) {
        // EINVAL can't happen - size argument > 0

        // PATH_MAX includes the terminating nul, 
        // so ERANGE should not be returned

        case EACCES:
            throw std::runtime_error("Access denied");

        case ENOMEM:
            // I'm not sure whether this can happen or not 
            throw std::runtime_error("Insufficient storage");

        default: {
            std::ostringstream str;
            str << "Unrecognised error" << error;
            throw std::runtime_error(str.str());
        }
    }
}

Дело в том, что при обертке библиотечной функции в другой функции вы должны предположить, что все функции должны быть открыты, потому что библиотека не знает, что ее вызовет. Поэтому вам приходится обрабатывать ошибки, а не просто глотать их или надеяться, что их не произойдет.

Как правило, лучше, чтобы код клиента просто вызывал библиотечную функцию и обрабатывал ошибку в этот момент - код клиента, вероятно, не волнует, почему произошла ошибка, и поэтому он должен обрабатывать только случай прохождения/отказа, а не кодами ошибок.

Ответ 4

Вам нужно просто написать небольшую обертку.

std::string getcwd_string( void ) {
   char buff[PATH_MAX];
   getcwd( buff, PATH_MAX );
   std::string cwd( buff );
   return cwd;
}

Ответ 5

Все функции C также являются функциями С++. Если вам нужен std::string, просто создайте его из char*, который получит getcwd.

Ответ 6

Я использовал getcwd() в C следующим образом:

char * cwd;
cwd = (char*) malloc( FILENAME_MAX * sizeof(char) );
getcwd(cwd,FILENAME_MAX);

Требуется файл заголовка stdio.h. Когда я использую компилятор C, он отлично работает.

Если я компилирую точно такой же код с помощью компилятора С++, он сообщает следующее сообщение об ошибке:

identifier "getcwd" is undefined

Затем я включил unistd.h и скомпилировал с компилятором С++. На этот раз все работает. Когда я переключился на компилятор C, он все равно работает!

Пока вы включаете как stdio.h, так и unistd.h, приведенный выше код работает для компиляторов C и С++.

Ответ 7

Я также использовал boost:: filesystem, как указано в другом ответе выше. Я просто хотел добавить, что поскольку функция current_path() не возвращает std::string, вам необходимо ее преобразовать.

Вот что я сделал:

std::string cwd = boost::filesystem::current_path().generic_string();

Ответ 8

Вы можете создать новую функцию, которую я бы предпочел связать с библиотекой, например boost (если вы уже не знаете).

 std::string getcwd()
 {
     char* buff;//automatically cleaned when it exits scope
     return std::string(getcwd(buff,255));
 }