Как построить полную строку пути (безопасно) из отдельных строк?

Имеет ли С++ эквивалент функции python os.path.join? В основном, я ищу что-то, что объединяет две (или более) части пути к файлу, так что вам не нужно беспокоиться о том, чтобы обе части идеально сочетались друг с другом. Если это в Qt, это тоже будет круто.

В основном я потратил час на отладку некоторого кода, и по крайней мере часть его состояла в том, что root + filename должен был быть root/ + filename, и я хочу избежать этого в будущем.

Ответ 1

Обратите внимание на QDir:

QString path = QDir(dirPath).filePath(fileName);

Ответ 2

Только как часть библиотека Boost.Filesystem. Вот пример:

#include <iostream>
#include <boost/filesystem.hpp>

namespace fs = boost::filesystem;

int main ()
{
    fs::path dir ("/tmp");
    fs::path file ("foo.txt");
    fs::path full_path = dir / file;
    std::cout << full_path << std::endl;
}

Вот пример компиляции и работы (для конкретной платформы):

$ g++ ./test.cpp -o test -lboost_filesystem -lboost_system
$ ./test 
/tmp/foo.txt

Ответ 3

Подобно user405725 ответ (но не используя boost) и упомянутый ildjarn в комментарии, эта функциональность доступна в составе файловой системы. Следующий код компилируется с использованием Microsoft Visual Studio 2015 Community Edition.

#include <iostream>
#include <filesystem>
namespace fs = std::experimental::filesystem;

int main() 
{
    fs::path dir ("/tmp");
    fs::path file ("foo.txt");
    fs::path full_path = dir / file;
    std::cout << full_path << std::endl;
}

Ответ 4

По крайней мере, в unix/linux всегда безопасно присоединяться к частям пути через /, даже если некоторые части пути уже завершены в /, то есть root/path эквивалентно корневому пути //. В этом случае все, что вам действительно нужно, это объединить вещи в /. Тем не менее, я согласен с другими плакатами, которые повышают:: файловую систему - хороший выбор, если он доступен вам, потому что он является многоплатформенным.

Ответ 5

Если вы хотите сделать это с помощью Qt, вы можете использовать конструктор QFileInfo:

 QFileInfo fi(QDir("/tmp"),"file");
 fi.absoluteFilePath(); //Return QString containing the path

Ответ 6

В Qt просто используйте '/' в коде при использовании Qt API (QFile, QFileInfo). Он будет делать все на всех платформах. Если вам нужно передать путь к функции, отличной от Qt, или хотите отформатировать ее для отображения ее пользователю, используйте QDir: toNativeSeparators()

QDir::toNativeSeparators( path )

Он заменит "/" на родным эквивалентом (т.е. "\" в Windows). Другое направление выполняется через QDir:: fromNativeSeparators().

Ответ 7

С С++ 11 и Qt вы можете сделать это:

QString join(const QString& v) {
    return v;
}

template<typename... Args>
QString join(const QString& first, Args... args) {
    return QDir(first).filePath(join(args...));
}

Использование:

QString path = join("/tmp", "dir", "file"); // /tmp/dir/file