Я вижу C getcwd через: человек 3 cwd
Я подозреваю, что C++ имеет подобный, который мог возвратить меня станд.:: строка.
Если так, чем это называют, и где я могу найти, что это - документация?
Спасибо!
Хорошо, я отвечаю, хотя вы уже приняли ответ.
Еще лучше, чем обернуть вызов getcwd, - это использовать boost :: filesystem , где вы получаете объект path
из current_path ()
] функция. Библиотека файловой системы Boost позволяет вам делать множество других полезных вещей, которые в противном случае вам потребовались бы для выполнения большого количества синтаксического анализа строк, например, проверка наличия файлов / каталогов, получение родительского пути, создание полных путей и так далее.Проверьте это, он также переносится - большая часть кода синтаксического анализа строк, который можно было бы использовать в противном случае, скорее всего, не будет.
Обновление (2016): Файловая система была опубликована в виде технической спецификации в 2015 году на основе Boost Filesystem v3. Это означает, что он может быть уже доступен в вашем компиляторе (например, Visual Studio 2015). Мне также кажется вероятным, что он станет частью будущего стандарта C ++ (я бы предположил, что C ++ 17, но я не знаю о текущем статусе).
Обновление (2017 г.): Библиотека файловой системы была объединена с ISO C ++ в C ++ 17 для
std::filesystem::current_path();
std :: string
Конструктор может безопасно принимать char *
в качестве параметра. Удивительно, но есть и версия для Windows .
Изменить: на самом деле это немного сложнее:
std::string get_working_path()
{
char temp[MAXPATHLEN];
return ( getcwd(temp, sizeof(temp)) ? std::string( temp ) : std::string("") );
}
С памятью проблем нет - temp - это стековый буфер, а конструктор std :: string делает копию.Возможно, вы могли бы сделать это за один раз, но я не думаю, что стандарт этого гарантирует.
О распределении памяти через POSIX:
Функция getcwd () помещает абсолютный путь к текущему рабочему каталогу в массив, на который указывает buf, и возвращает buf. Путь , скопированный в массив, не должен содержать компонентов, которые являются символическими ссылками. Аргумент размера - это размер в байтах символьного массива, на который указывает аргумент buf. Если buf - нулевой указатель, поведение getcwd () не определено.
Все функции C также являются функциями C ++. Если вам нужен std :: string
, просто создайте его из char *
, полученного getcwd.
Давайте попробуем переписать этот простой вызов C как 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());
}
}
}
Дело в том, что при переносе библиотечной функции в другую функцию вы должны предположить, что все функциональность должна быть раскрыта, потому что библиотека не знает, что ее будет вызывать. Таким образом, вы должны обрабатывать случаи ошибок, а не просто проглатывать их или надеяться, что их не произойдет.
Обычно лучше позволить клиентскому коду просто вызвать библиотечную функцию и обработать ошибку в этот момент - клиентскому коду, вероятно, безразлично, почему произошла ошибка, поэтому он должен обрабатывать только случай «прошел / не прошел». , а не все коды ошибок.
Вам нужно просто написать небольшую обертку.
std::string getcwd_string( void ) {
char buff[PATH_MAX];
getcwd( buff, PATH_MAX );
std::string cwd( buff );
return cwd;
}