별도의 문자열에서 전체 경로 문자열을 (안전하게) 만드는 방법은 무엇입니까?


91

C ++에는 파이썬의 기능과 동등한 것이 os.path.join있습니까? 기본적으로 파일 경로의 두 부분 (또는 그 이상)을 결합하는 것을 찾고 있으므로 두 부분이 완벽하게 맞도록하는 것에 대해 걱정할 필요가 없습니다. Qt에 있다면 그것도 멋질 것입니다.

기본적으로 나는 몇 가지 코드를 디버깅 시간을 소비하기 때문에 그것의 적어도 일부에 있었다 root + filename있어야했다 root/ + filename, 나는 미래에 있음을 피하기 위해 찾고 있어요.


아마 멀리 떨어진 : stackoverflow.com/questions/5772992/... (특히, 관련 질문은 부스트의입니다 complete)
궤도의 밝기 경주

답변:


45

이에 대한 QDir 을 확인하십시오 .

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

3
Qt가 GPL이라는 점에 유의하십시오. 많은 용도로 거래 차단기가 될 수 있습니다.
rustyx

3
@RustyX 정확히 말하자면 LGPL입니다.
Pa_

98

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;
    return 0;
}

다음은 컴파일 및 실행의 예입니다 (플랫폼 별) :

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

1
이것은 내년에 컴파일러와 함께 출시 될 가능성이있는 TR2에도 있습니다.
ildjarn 2011 년

1
@Vlad : 예, 쉽게 찾을 수는 없지만 Boost 문서 링크를 클릭하고 뒤늦게 이전 버전을보고 있다는 사실을 깨닫는 것이 싫기 때문에 사람들의 버전 별 링크를 발견하면 편집합니다. - P
ildjarn

1
@ildjarn : 지금은 잘 작동하는 것 같습니다 ...하지만 주어진 라이브러리의 사이트 또는 문서에 대해 뭔가를 변경할 때까지 기다리십시오. 그때부터 버전 별 링크를 떠나는 것보다 더 나쁩니다.
Fred Nurk 2011 년

1
@Fred : 분명히 기능이나 질문이 버전에 따라 다르면 URL을 변경하지 않습니다. 이 경우에는 그렇지 않습니다.
ildjarn 2011 년

1
@ildjarn : 편집 한 모든 답변이 향후 모든 버전에 대해 의미가 있는지 알 수 있도록 주어진 라이브러리가 앞으로 변경 될 내용을 어떻게 예측합니까?
Fred Nurk 2011 년

24

유사 @ user405725 의 대답 (그러나 부스트를 사용하지 않음)에 의해 언급 @ildjarn 코멘트에서,이 기능의 일부로 볼 수 있습니다 표준 : 파일 시스템 . 다음 코드는 Homebrew GCC 9.2.0_1과 플래그를 사용하여 컴파일됩니다 --std=c++17.

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

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

4
C ++ 17에서 이것은 (실험적이지 않은) <filesystem> 헤더에 병합되었습니다. en.cppreference.com/w/cpp/filesystem을 참조하십시오 .
Eli_B

9

유닉스 / 리눅스에서 적어도, 그것은에 의해 경로의 일부를 가입하는 것이 안전 /경로의 일부가 이미 종료하더라도 /, 즉 root/path동일합니다 root//path.

이 경우 정말 필요한 것은 /. 즉, boost::filesystem여러 플랫폼을 지원하기 때문에 가능한 경우 좋은 선택 인 다른 답변에 동의 합니다.


2
QT는 경로 구분 기호와 무관합니다. Windows에서 파일의 절대 경로를 인쇄하는 경우 출력은 / (unix) 구분 기호가있는 "C : /Users/Name/MyFile.txt"입니다. boost :: filesystem은 훌륭하지만 프로젝트가 Qt 기반이라면 boost 라이브러리에 대한 종속성을 추가 할 필요가 없습니다.
LoSciamano 2011 년

7

Qt로이 작업을 수행하려면 QFileInfo생성자 를 사용할 수 있습니다 .

QFileInfo fi( QDir("/tmp"), "file" );
QString path = fi.absoluteFilePath();

4

C ++ 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

3

Qt에서는 Qt /API ( QFile, QFileInfo) 를 사용할 때 코드에서 사용하십시오 . 모든 플랫폼에서 올바른 일을 할 것입니다. 비 Qt 함수에 경로를 전달해야하거나 사용자에게 표시하기 위해 형식을 지정하려면 다음을 사용하십시오 QDir:toNativeSeparators().

QDir::toNativeSeparators( path );

/기본적으로 해당하는 것으로 대체 됩니다 (예 : \Windows). 다른 방향은를 통해 수행됩니다 QDir::fromNativeSeparators().

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.