경로에서 파일 이름 가져 오기


82

경로에서 파일 이름을 얻는 가장 간단한 방법은 무엇입니까?

string filename = "C:\\MyDirectory\\MyFile.bat"

이 예에서는 "MyFile"을 가져와야합니다. 확장없이.


1
백 스페이스를 칠 때까지 뒤에서 검색 하시겠습니까?
Kerrek SB

2
@KerrekSB, 당신은 백 슬래시 를 의미 합니다 ;)
Nim

"c : \\ MyDirectory \\ Myfile.pdf"파일의 경로를 포함하는 std :: string이 있습니다.이 파일의 이름을 myfile_md.pdf로 변경해야하므로 경로에서 파일 이름을 가져와야합니다.
nidhal

1
파일 경로로 많은 작업을해야하는 경우 Boost FileSystem 사용을 고려하십시오. boost.org/doc/libs/release/libs/filesystem/v3/doc/index.htm
edA-qa mort-ora-y

2
@Nim : 네! 나는 간격을두고 있었음에 틀림 없다 ...
Kerrek SB

답변:


29

_splitpath 는 필요한 작업을 수행해야합니다. 물론 수동으로 할 수 있지만 _splitpath모든 특수한 경우도 처리합니다.

편집하다:

BillHoag가 언급했듯이 가능한 경우 _splitpath_s_splitpath 라는 더 안전한 버전을 사용하는 것이 좋습니다 .

또는 휴대용 무언가를 원한다면 다음과 같이 할 수 있습니다.

std::vector<std::string> splitpath(
  const std::string& str
  , const std::set<char> delimiters)
{
  std::vector<std::string> result;

  char const* pch = str.c_str();
  char const* start = pch;
  for(; *pch; ++pch)
  {
    if (delimiters.find(*pch) != delimiters.end())
    {
      if (start != pch)
      {
        std::string str(start, pch);
        result.push_back(str);
      }
      else
      {
        result.push_back("");
      }
      start = pch + 1;
    }
  }
  result.push_back(start);

  return result;
}

...
std::set<char> delims{'\\'};

std::vector<std::string> path = splitpath("C:\\MyDirectory\\MyFile.bat", delims);
cout << path.back() << endl;

2
_splitpath내 컴퓨터에 포함 된 항목 이 없습니다 .
James Kanze 2011

9
나는 Visual Studio를 가지고 g ++, 썬 CC를. 완벽하게 좋은 휴대용 솔루션이 있는데 왜 비표준을 사용해야합니까?
James Kanze 2011

2
@James, 링크 된 페이지에 <stdlib.h>. 이식성에 관해서는 "완벽하게 좋은 휴대용 솔루션"의 몇 가지 예를 나열 할 수 있습니까?
Synetech

2
@Synetech 링크 된 페이지는 <stdlib.h>. 그리고 명백한 휴대용 솔루션은 boost::filesystem.
James Kanze

3
@ 제임스, 당신은 필요가 없습니다 _splitpath에서 stdlib.hVS 사본의? 그런 다음 VS의 수리 설치를 원할 수 있습니다.
Synetech

62

가능한 해결책 :

string filename = "C:\\MyDirectory\\MyFile.bat";

// Remove directory if present.
// Do this before extension removal incase directory has a period character.
const size_t last_slash_idx = filename.find_last_of("\\/");
if (std::string::npos != last_slash_idx)
{
    filename.erase(0, last_slash_idx + 1);
}

// Remove extension if present.
const size_t period_idx = filename.rfind('.');
if (std::string::npos != period_idx)
{
    filename.erase(period_idx);
}

가장 단순한 것이 항상 최고입니다!
Jean-François Fabre

60

기본 파일 이름이 폴더의 마지막 구분자에서 시작하는 문자열의 일부이기 때문에 작업은 매우 간단합니다.

std::string base_filename = path.substr(path.find_last_of("/\\") + 1)

확장 기능도 제거해야하는 경우 마지막 .작업 substr을 찾아이 지점까지 가져 가야합니다.

std::string::size_type const p(base_filename.find_last_of('.'));
std::string file_without_extension = base_filename.substr(0, p);

확장으로 만 구성된 파일 (예 : .bashrc...) 에 대처하기위한 검사가 있어야합니다.

이것을 별도의 함수로 분할하면 단일 작업을 유연하게 재사용 할 수 있습니다.

template<class T>
T base_name(T const & path, T const & delims = "/\\")
{
  return path.substr(path.find_last_of(delims) + 1);
}
template<class T>
T remove_extension(T const & filename)
{
  typename T::size_type const p(filename.find_last_of('.'));
  return p > 0 && p != T::npos ? filename.substr(0, p) : filename;
}

코드는 다른 std::basic_string인스턴스 (예 : std::string& std::wstring...) 와 함께 사용할 수 있도록 템플릿 화되어 있습니다 .

템플릿의 단점은 a const char *가 함수에 전달되는 경우 템플릿 매개 변수를 지정해야 한다는 것입니다.

따라서 다음 중 하나를 수행 할 수 있습니다.

A) std::string코드 템플릿 대신 사용

std::string base_name(std::string const & path)
{
  return path.substr(path.find_last_of("/\\") + 1);
}

B) 사용하여 랩핑 기능 제공 std::string(인라인 / 최적화 될 가능성이있는 중간체)

inline std::string string_base_name(std::string const & path)
{
  return base_name(path);
}

C)로 호출 할 때 템플릿 매개 변수를 지정합니다 const char *.

std::string base = base_name<std::string>("some/path/file.ext");

결과

std::string filepath = "C:\\MyDirectory\\MyFile.bat";
std::cout << remove_extension(base_name(filepath)) << std::endl;

인쇄물

MyFile

이 사용 사례에서는 모든 것이 정상이지만 (원래 질문에 답이 있음) 확장 제거 프로그램이 완벽하지 않습니다. "/home/user/my.dir/myfile"과 같은 것을 전달하면 실패합니다.
avtomaton

@avtomaton 확장자 제거 기능은 경로가 아닌 파일 이름에 사용해야합니다. (그냥 적용 base_name첫째.)
Pixelchemist

나는 그것을 이해합니다 (그래서 원래 질문에 대한 답을 썼고이 사용 사례에서는 모든 것이 괜찮습니다). 이 스 니펫을 사용하려는 누군가를 위해이 문제를 지적하고 싶었습니다.
avtomaton 2015-08-27

아주 좋은 설명입니다. 문제의 구조적 이해를 향상시킵니다. 감사합니다
hell_ical_vortex

38

가장 간단한 해결책은 boost::filesystem. 어떤 이유로 이것이 옵션이 아닌 경우 ...

이 작업을 올바르게 수행하려면 일부 시스템 종속 코드가 필요합니다. Windows에서는 '\\'또는 '/'경로 구분 기호 일 수 있습니다. 유닉스에서는 '/'작동하며 다른 시스템에서는 알 수 있습니다. 명백한 해결책은 다음과 같습니다.

std::string
basename( std::string const& pathname )
{
    return std::string( 
        std::find_if( pathname.rbegin(), pathname.rend(),
                      MatchPathSeparator() ).base(),
        pathname.end() );
}

, MatchPathSeparator시스템 종속 헤더에 다음 중 하나로 정의됩니다.

struct MatchPathSeparator
{
    bool operator()( char ch ) const
    {
        return ch == '/';
    }
};

Unix의 경우 또는 :

struct MatchPathSeparator
{
    bool operator()( char ch ) const
    {
        return ch == '\\' || ch == '/';
    }
};

Windows의 경우 (또는 다른 알 수없는 시스템에서는 여전히 다른 것).

편집 : 나는 그가 또한 확장을 억제하고 싶다는 사실을 놓쳤습니다. 이를 위해 더 많은 것 :

std::string
removeExtension( std::string const& filename )
{
    std::string::const_reverse_iterator
                        pivot
            = std::find( filename.rbegin(), filename.rend(), '.' );
    return pivot == filename.rend()
        ? filename
        : std::string( filename.begin(), pivot.base() - 1 );
}

코드는 조금 더 복잡합니다. 왜냐하면이 경우 역방향 반복기의베이스가 잘라 내고자하는 곳의 잘못된쪽에 있기 때문입니다. (역방향 반복기의베이스는 반복기가 가리키는 문자 뒤에 있다는 것을 기억하십시오.) 그리고 이것은 조금 모호합니다. 예를 들어 빈 문자열을 반환 할 수 있다는 사실이 마음에 들지 않습니다. (만일 '.'파일 이름의 첫 번째 문자 만 있다면 전체 파일 이름을 반환해야한다고 주장합니다. 특수한 경우를 포착하려면 약간의 추가 코드가 필요합니다.)}


9
string::find_last_of역방향 반복자를 조작 하는 대신 사용 하는 것은 어떻습니까?
Luc Touraille 2011

@LucTouraille 한 사람이 일을 할 때 두 가지 방법을 배우는 이유는 무엇입니까? 를 제외한 모든 컨테이너에 대해 역 반복기가 필요 string하므로 어쨌든 배워야합니다. 그리고 그것들을 배웠으므로 .NET에 대한 모든 부풀어 오른 인터페이스를 배우는 데 신경 쓸 이유가 없습니다 std::string.
James Kanze 2011

참고 : <filesystem> 헤더는 Visual Studio 2015 이상과 함께 제공되므로 사용하기 위해 부스트에 대한 종속성을 추가 할 필요가 없습니다.
IInspectable

15

셸 경로 API PathFindFileName, PathRemoveExtension을 사용할 수도 있습니다. 이 특정 문제에 대해 _splitpath보다 나쁠 수 있지만 이러한 API는 모든 종류의 경로 구문 분석 작업에 매우 유용하며 UNC 경로, 슬래시 및 기타 이상한 사항을 고려합니다.

wstring filename = L"C:\\MyDirectory\\MyFile.bat";
wchar_t* filepart = PathFindFileName(filename.c_str());
PathRemoveExtension(filepart); 

http://msdn.microsoft.com/en-us/library/windows/desktop/bb773589(v=vs.85).aspx

단점은 shlwapi.lib에 연결해야한다는 것입니다.하지만 이것이 왜 단점인지 잘 모르겠습니다.


경로에서 파일 이름을 얻는 데 선호하는 솔루션입니다.
Andreas

15

부스트를 사용할 수 있다면

#include <boost/filesystem.hpp>
path p("C:\\MyDirectory\\MyFile.bat");
string basename = p.filename().string();
//or 
//string basename = path("C:\\MyDirectory\\MyFile.bat").filename().string();

이게 다야.

부스트 라이브러리 사용을 권장합니다. Boost는 C ++로 작업 할 때 많은 편의를 제공합니다. 거의 모든 플랫폼을 지원합니다. Ubuntu를 사용하는 경우 한 줄로 부스트 라이브러리를 설치할 수 있습니다 sudo apt-get install libboost-all-dev(참조. Ubuntu에 부스트를 설치하는 방법? ).


14

C ++ 17에서 가장 간단한 방법은 다음과 같습니다.

사용 #include <filesystem>filename()확장자와 파일 이름을 stem()확장자없이.

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

    int main()
    {
        string filename = "C:\\MyDirectory\\MyFile.bat";

    std::cout << fs::path(filename).filename() << '\n'
        << fs::path(filename).stem() << '\n'
        << fs::path("/foo/bar.txt").filename() << '\n'
        << fs::path("/foo/bar.txt").stem() << '\n'
        << fs::path("/foo/.bar").filename() << '\n'
        << fs::path("/foo/bar/").filename() << '\n'
        << fs::path("/foo/.").filename() << '\n'
        << fs::path("/foo/..").filename() << '\n'
        << fs::path(".").filename() << '\n'
        << fs::path("..").filename() << '\n'
        << fs::path("/").filename() << '\n';
    }

산출:

MyFile.bat
MyFile
"bar.txt"
".bar"
"."
"."
".."
"."
".."
"/"

참조 : cppreference


그것은 더 이상 "실험"에없는
비타

13

함수:

#include <string>

std::string
basename(const std::string &filename)
{
    if (filename.empty()) {
        return {};
    }

    auto len = filename.length();
    auto index = filename.find_last_of("/\\");

    if (index == std::string::npos) {
        return filename;
    }

    if (index + 1 >= len) {

        len--;
        index = filename.substr(0, len).find_last_of("/\\");

        if (len == 0) {
            return filename;
        }

        if (index == 0) {
            return filename.substr(1, len - 1);
        }

        if (index == std::string::npos) {
            return filename.substr(0, len);
        }

        return filename.substr(index + 1, len - index - 1);
    }

    return filename.substr(index + 1, len - index);
}

테스트 :

#define CATCH_CONFIG_MAIN
#include <catch/catch.hpp>

TEST_CASE("basename")
{
    CHECK(basename("") == "");
    CHECK(basename("no_path") == "no_path");
    CHECK(basename("with.ext") == "with.ext");
    CHECK(basename("/no_filename/") == "no_filename");
    CHECK(basename("no_filename/") == "no_filename");
    CHECK(basename("/no/filename/") == "filename");
    CHECK(basename("/absolute/file.ext") == "file.ext");
    CHECK(basename("../relative/file.ext") == "file.ext");
    CHECK(basename("/") == "/");
    CHECK(basename("c:\\windows\\path.ext") == "path.ext");
    CHECK(basename("c:\\windows\\no_filename\\") == "no_filename");
}

8

C ++ 문서에서 -string :: find_last_of

#include <iostream>       // std::cout
#include <string>         // std::string

void SplitFilename (const std::string& str) {
  std::cout << "Splitting: " << str << '\n';
  unsigned found = str.find_last_of("/\\");
  std::cout << " path: " << str.substr(0,found) << '\n';
  std::cout << " file: " << str.substr(found+1) << '\n';
}

int main () {
  std::string str1 ("/usr/bin/man");
  std::string str2 ("c:\\windows\\winhelp.exe");

  SplitFilename (str1);
  SplitFilename (str2);

  return 0;
}

출력 :

Splitting: /usr/bin/man
 path: /usr/bin
 file: man
Splitting: c:\windows\winhelp.exe
 path: c:\windows
 file: winhelp.exe

아무것도 발견되지 않으면 find_last_of반환 string::npos되는 것을 잊지 마십시오 (그리고 처리해야 합니다 ) .
congusbongus

@congusbongus 사실,하지만 :) 그냥 파일 이름 (경로없이) 인 파일 경로 때 분할의 아무 의미가 없다
jave.web

@ jave.web 그것은 의미가 있으며 반환 'string :: npos'를 처리해야합니다. 이를위한 함수를 구현하면 "파일 이름 만"을 포함한 다양한 입력을 처리 할 수 ​​있어야합니다. 그렇지 않으면 실제 구현에서 버그가 있으면 쓸모가 없습니다.
winux

@winux 이것은 이미 유효한 PATHS를 고려 합니다 ... 입력을 신뢰하지 않는 경우, 물론 경로를 먼저 확인해야합니다.
jave.web

@winux 어쨌든string::npos 이것과 string::substr구현 방법 때문에 검사를 수행 할 필요가 없습니다 . a) string::npos "length"=> substr끝까지 모두 읽는 동작이 문서화 되어 전달됩니다 . b) substr" string::npos + 1" 가 주어지고 길이 없음 : string::npos값이으로 문서화되어 -1있으므로 0=> 문자열의 시작과 길이의 기본값 substrnpos=> "파일 이름 만"에서도 작동합니다. cplusplus.com/reference / 문자열 / 문자열 / SUBSTR의 cplusplus.com/reference/string/string/npos
jave.web

5

균일 한 초기화 및 익명 인라인 람다를 사용하는 C ++ 11 변형 (James Kanze 버전에서 영감을 얻음).

std::string basename(const std::string& pathname)
{
    return {std::find_if(pathname.rbegin(), pathname.rend(),
                         [](char c) { return c == '/'; }).base(),
            pathname.end()};
}

하지만 파일 확장자를 제거하지는 않습니다.


짧고 달콤하지만 Windows가 아닌 경로에서만 작동합니다.
Volomike 2016 년

당신은 항상 람다 수익을 변경할 수 return c == '/' || c == '\\';는 윈도우에서 작동하도록
ziomq1991

"", "///"및 "dir1 / dir2 /"와 같은 경로를 처리하려면 위의 return 문 앞에 다음 코드를 추가합니다 (참조 : POSIX basename ()) : if (pathname.size() == 0) return "."; auto iter = pathname.rbegin(); auto rend = pathname.rend(); while (iter != rend && *iter == '/') ++iter; if (iter == rend) /* pathname has only path separators */ return "/"; pathname = std::string(pathname.begin(), iter.base());
Gidfiddle

5

boost filesystem라이브러리는 또한으로 사용할 experimental/filesystem라이브러리와 C ++ (17)에 대한 ++ ISO C에 합병되었다. 다음과 같이 사용할 수 있습니다.

#include <iostream>
#include <experimental/filesystem>

namespace fs = std::experimental::filesystem;

int main () {
    std::cout << fs::path("/foo/bar.txt").filename() << '\n'
}

산출:

"bar.txt"

그것은 또한 std::string개체에 대해 작동 합니다.


4

이것은 실제로 마침내 나를 위해 일한 유일한 것입니다.

#include "Shlwapi.h"

CString some_string = "c:\\path\\hello.txt";
LPCSTR file_path = some_string.GetString();
LPCSTR filepart_c = PathFindFileName(file_path);
LPSTR filepart = LPSTR(filepart_c);
PathRemoveExtension(filepart);

Skrymsli가 제안한 것과 거의 비슷하지만 wchar_t *, VS Enterprise 2015에서는 작동하지 않습니다.

_splitpath도 작동했지만 얼마나 많은 char [?] 문자가 필요한지 추측 할 필요가 없습니다. 어떤 사람들은 아마도이 컨트롤이 필요할 것 같습니다.

CString c_model_name = "c:\\path\\hello.txt";
char drive[200];
char dir[200];
char name[200];
char ext[200];
_splitpath(c_model_name, drive, dir, name, ext);

_splitpath에 대한 포함이 필요하지 않다고 생각합니다. 이러한 솔루션에는 외부 라이브러리 (예 : 부스트)가 필요하지 않았습니다.


4
std::string getfilename(std::string path)
{
    path = path.substr(path.find_last_of("/\\") + 1);
    size_t dot_i = path.find_last_of('.');
    return path.substr(0, dot_i);
}

3

나는 그것을 할 것입니다 ...

첫 번째 백 슬래시 / 슬래시를 찾을 때까지 문자열 끝에서 뒤로 검색합니다.

그런 다음 첫 번째 점 (.)을 찾을 때까지 문자열 끝에서 뒤로 검색합니다.

그러면 파일 이름의 시작과 끝이 있습니다.

단순 ...


내가 아는 어떤 시스템에서도 작동하지 않습니다. ( '\\'경로 구분자로 받아들이는 하나의 시스템 도를 사용 '/'하므로 둘 중 하나를 일치시켜야합니다.) 그리고 무엇을 기대할지 모르겠습니다.
James Kanze 2011

좋아, 둘 중 하나와 일치하도록 수정하십시오. 그리고 첫 번째 점 (.)을 기대합니다.
TomP89

여전히 첫 번째가 아닌 마지막 점을 찾아야합니다. (역방향 반복자는 당신의 친구입니다!)
제임스 간제

아 그래, 좋은 지적이야. 따라서 file.ext.ext의 경우 file.ext를 추출하고 싶을 것입니다. :)
TomP89 2011

아마도. 이것은 어떤 경우에도 일반적인 규칙입니다 : 예를 들어 (확장은으로 대체 됨 ) 로 my.source.cpp컴파일됩니다 . my.source.obj.cpp.obj
James Kanze 2011

2
m_szFilePath.MakeLower();
CFileFind finder;
DWORD buffSize = MAX_PATH;
char longPath[MAX_PATH];
DWORD result = GetLongPathName(m_szFilePath, longPath, MAX_PATH );

if( result == 0)
{
    m_bExists = FALSE;
    return;
}
m_szFilePath = CString(longPath);
m_szFilePath.Replace("/","\\");
m_szFilePath.Trim();
//check if it does not ends in \ => remove it
int length = m_szFilePath.GetLength();
if( length > 0 && m_szFilePath[length - 1] == '\\' )
{
    m_szFilePath.Truncate( length - 1 );
}
BOOL bWorking = finder.FindFile(this->m_szFilePath);
if(bWorking){
    bWorking = finder.FindNextFile();
    finder.GetCreationTime(this->m_CreationTime);
    m_szFilePath = finder.GetFilePath();
    m_szFileName = finder.GetFileName();

    this->m_szFileExtension = this->GetExtension( m_szFileName );

    m_szFileTitle = finder.GetFileTitle();
    m_szFileURL = finder.GetFileURL();
    finder.GetLastAccessTime(this->m_LastAccesTime);
    finder.GetLastWriteTime(this->m_LastWriteTime);
    m_ulFileSize = static_cast<unsigned long>(finder.GetLength());
    m_szRootDirectory = finder.GetRoot();
    m_bIsArchive = finder.IsArchived();
    m_bIsCompressed = finder.IsCompressed();
    m_bIsDirectory = finder.IsDirectory();
    m_bIsHidden = finder.IsHidden();
    m_bIsNormal = finder.IsNormal();
    m_bIsReadOnly = finder.IsReadOnly();
    m_bIsSystem = finder.IsSystem();
    m_bIsTemporary = finder.IsTemporary();
    m_bExists = TRUE;
    finder.Close();
}else{
    m_bExists = FALSE;
}

m_szFileName 변수에는 fileName이 포함됩니다.


3
와우-경로에서 "파일 이름 가져 오기"에 대한 많은 코드입니다 ... :)
Nim

4
@Nim 내 인상도. 내 코드에서는 한 줄짜리 boost::filesystem::path( path ).filename().
James Kanze

해당 코드가있는 CFileInfo 클래스가 있습니다. 테스트를 거쳤고 위험을 감수하고 싶지 않았기 때문에 여기에 코드를 덤핑했습니다.이 예제에서 약 5 줄의 코드를 사용할 수 있습니다.
Lucian


2

이것도 작동합니다.

// strPath = "C:\\Dir\\File.bat" for example
std::string getFileName(const std::string& strPath)
{
    size_t iLastSeparator = 0;
    return strPath.substr((iLastSeparator = strPath.find_last_of("\\")) != std::string::npos ? iLastSeparator + 1 : 0, strPath.size() - strPath.find_last_of("."));
}

당신이 그것을 사용할 수 있다면, Qt는 파일, 파일 이름 및 디렉토리를 조작하기 위해 QString (분할, 트림 등), QFile, QPath, QFileInfo 등을 제공합니다. 그리고 물론 그것은 교차 플랫폼이기도합니다.


4
미래의 코드 독자를 위해 모든 것을 한 줄의 코드로 채우는 대신 의미있는 이름을 가진 임시 변수를 사용하십시오 (그리고이 모든 것을 함수 getFilename또는 이와 유사한 것으로 캡슐화하십시오 ).
Luc Touraille 2011

편집. 그러나 몇 가지 작업 답변이 이미 주어 졌기 때문에 요점은 짧게 만드는 것이 었습니다.
typedef

1
나는 그것이 잘못된 것이라고 생각합니다. 마지막 부분 : "strPath.size ()-strPath.find_last_of (". ")"를 "strPath.find_last_of (". ")로 바꾸면 안됩니다.-iLastSeparator"
taktak004 2014 년

@ taktak004 당신이 맞습니다.`return strPath.substr ((iLastSeparator = strPath.find_last_of ( "/"))! = std :: string :: npos? iLastSeparator + 1 : 0, strPath.find_last_of ( "." )-iLastSeparator);`
phenmod

2

std :: filesystem을 사용하여 아주 멋지게 할 수 있습니다.

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

fs::path myFilePath("C:\\MyDirectory\\MyFile.bat");
fs::path filename = myFilePath.stem();

0

오랫동안 파일 경로를 적절하게 분해 할 수있는 기능을 찾고있었습니다. 저에게이 코드는 Linux와 Windows 모두에서 완벽하게 작동합니다.

void decomposePath(const char *filePath, char *fileDir, char *fileName, char *fileExt)
{
    #if defined _WIN32
        const char *lastSeparator = strrchr(filePath, '\\');
    #else
        const char *lastSeparator = strrchr(filePath, '/');
    #endif

    const char *lastDot = strrchr(filePath, '.');
    const char *endOfPath = filePath + strlen(filePath);
    const char *startOfName = lastSeparator ? lastSeparator + 1 : filePath;
    const char *startOfExt = lastDot > startOfName ? lastDot : endOfPath;

    if(fileDir)
        _snprintf(fileDir, MAX_PATH, "%.*s", startOfName - filePath, filePath);

    if(fileName)
        _snprintf(fileName, MAX_PATH, "%.*s", startOfExt - startOfName, startOfName);

    if(fileExt)
        _snprintf(fileExt, MAX_PATH, "%s", startOfExt);
}

결과 예는 다음과 같습니다.

[]
  fileDir:  ''
  fileName: ''
  fileExt:  ''

[.htaccess]
  fileDir:  ''
  fileName: '.htaccess'
  fileExt:  ''

[a.exe]
  fileDir:  ''
  fileName: 'a'
  fileExt:  '.exe'

[a\b.c]
  fileDir:  'a\'
  fileName: 'b'
  fileExt:  '.c'

[git-archive]
  fileDir:  ''
  fileName: 'git-archive'
  fileExt:  ''

[git-archive.exe]
  fileDir:  ''
  fileName: 'git-archive'
  fileExt:  '.exe'

[D:\Git\mingw64\libexec\git-core\.htaccess]
  fileDir:  'D:\Git\mingw64\libexec\git-core\'
  fileName: '.htaccess'
  fileExt:  ''

[D:\Git\mingw64\libexec\git-core\a.exe]
  fileDir:  'D:\Git\mingw64\libexec\git-core\'
  fileName: 'a'
  fileExt:  '.exe'

[D:\Git\mingw64\libexec\git-core\git-archive.exe]
  fileDir:  'D:\Git\mingw64\libexec\git-core\'
  fileName: 'git-archive'
  fileExt:  '.exe'

[D:\Git\mingw64\libexec\git.core\git-archive.exe]
  fileDir:  'D:\Git\mingw64\libexec\git.core\'
  fileName: 'git-archive'
  fileExt:  '.exe'

[D:\Git\mingw64\libexec\git-core\git-archiveexe]
  fileDir:  'D:\Git\mingw64\libexec\git-core\'
  fileName: 'git-archiveexe'
  fileExt:  ''

[D:\Git\mingw64\libexec\git.core\git-archiveexe]
  fileDir:  'D:\Git\mingw64\libexec\git.core\'
  fileName: 'git-archiveexe'
  fileExt:  ''

나는 이것이 당신에게도 도움이되기를 바랍니다 :)


0

shlwapi.lib/dllHKCU레지스트리 하이브를 내부적으로 사용합니다 .

shlwapi.lib라이브러리를 만들거나 제품에 UI가없는 경우 연결하지 않는 것이 가장 좋습니다 . lib를 작성하는 경우 UI가없는 프로젝트를 포함하여 모든 프로젝트에서 코드를 사용할 수 있습니다.

사용자가 로그인하지 않았을 때 실행되는 코드를 작성하는 경우 (예 : 부팅 또는 시작시 시작하도록 설정된 서비스 또는 기타) HKCU. 마지막으로 shlwapi는 결제 기능입니다. 그 결과 목록에서 상위 Windows 버전에서 더 이상 사용되지 않습니다.


0

느리지 만 직접적인 정규식 솔루션 :

    std::string file = std::regex_replace(path, std::regex("(.*\\/)|(\\..*)"), "");
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.