C ++의 경로에서 파일 이름과 확장명을 어떻게 추출 할 수 있습니까?
.log
이 구문에 저장된 파일 목록 이 있습니다.
c:\foto\foto2003\shadow.gif
D:\etc\mom.jpg
이 파일에서 이름과 확장자를 추출하고 싶습니다. 이를 수행하는 간단한 방법의 예를 들어 줄 수 있습니까?
확장자없이 파일 이름을 추출하려면 추악한 std :: string :: find_last_of ( ".") 대신 boost :: filesystem :: path :: stem을 사용하십시오.
boost::filesystem::path p("c:/dir/dir/file.ext");
std::cout << "filename and extension : " << p.filename() << std::endl; // file.ext
std::cout << "filename only : " << p.stem() << std::endl; // file
안전한 방법 (예 : 플랫폼간에 이식 가능하고 경로에 가정을 두지 않음)을 원하면을 사용하는 것이 좋습니다 boost::filesystem
.
어떻게 든 다음과 같이 보일 것입니다.
boost::filesystem::path my_path( filename );
그런 다음이 경로에서 다양한 데이터를 추출 할 수 있습니다. 다음은 경로 객체에 대한 문서입니다.
BTW : 또한 다음과 같은 경로를 사용하려면
c:\foto\foto2003\shadow.gif
\
문자열 리터럴에서 이스케이프해야합니다 .
const char* filename = "c:\\foto\\foto2003\\shadow.gif";
또는 /
대신 사용 :
const char* filename = "c:/foto/foto2003/shadow.gif";
이는 ""
따옴표로 묶인 리터럴 문자열을 지정하는 경우에만 적용되며 파일에서 경로를로드 할 때 문제가 발생하지 않습니다.
들어 C ++ 17 :
#include <filesystem>
std::filesystem::path p("c:/dir/dir/file.ext");
std::cout << "filename and extension: " << p.filename() << std::endl; // "file.ext"
std::cout << "filename only: " << p.stem() << std::endl; // "file"
파일 시스템에 대한 참조 : http://en.cppreference.com/w/cpp/filesystem
@RoiDanto 에서 제안한대로 출력 형식의 std::out
경우 출력을 인용 부호 로 묶을 수 있습니다. 예 :
filename and extension: "file.ext"
당신은 변환 할 수 있습니다 std::filesystem::path
에 std::string
의해 p.filename().string()
그건 당신이, 예를 들어, 필요하다면 :
filename and extension: file.ext
.NET의 파일에서 파일 이름을 읽어야합니다 std::string
. 의 문자열 추출 연산자를 사용할 수 있습니다 std::ostream
. 에 파일 이름이 있으면 메서드를 std::string
사용 std::string::find_last_of
하여 마지막 구분 기호를 찾을 수 있습니다 .
이 같은:
std::ifstream input("file.log");
while (input)
{
std::string path;
input >> path;
size_t sep = path.find_last_of("\\/");
if (sep != std::string::npos)
path = path.substr(sep + 1, path.size() - sep - 1);
size_t dot = path.find_last_of(".");
if (dot != std::string::npos)
{
std::string name = path.substr(0, dot);
std::string ext = path.substr(dot, path.size() - dot);
}
else
{
std::string name = path;
std::string ext = "";
}
}
Not the code, but here is the idea:
- Read a
std::string
from the input stream (std::ifstream
), each instance read will be the full path - Do a
find_last_of
on the string for the\
- Extract a substring from this position to the end, this will now give you the file name
- Do a
find_last_of
for.
, and a substring either side will give you name + extension.
I also use this snippet to determine the appropriate slash character:
boost::filesystem::path slash("/");
boost::filesystem::path::string_type preferredSlash = slash.make_preferred().native();
and then replace the slashes with the preferred slash for the OS. Useful if one is constantly deploying between Linux/Windows.
For linux or unix machines, the os has two functions dealing with path and file names. use man 3 basename to get more information about these functions. The advantage of using the system provided functionality is that you don't have to install boost or needing to write your own functions.
#include <libgen.h>
char *dirname(char *path);
char *basename(char *path);
Example code from the man page:
char *dirc, *basec, *bname, *dname;
char *path = "/etc/passwd";
dirc = strdup(path);
basec = strdup(path);
dname = dirname(dirc);
bname = basename(basec);
printf("dirname=%s, basename=%s\n", dname, bname);
Because of the non-const argument type of the basename() function, it is a little bit non-straight forward using this inside C++ code. Here is a simple example from my code base:
string getFileStem(const string& filePath) const {
char* buff = new char[filePath.size()+1];
strcpy(buff, filePath.c_str());
string tmp = string(basename(buff));
string::size_type i = tmp.rfind('.');
if (i != string::npos) {
tmp = tmp.substr(0,i);
}
delete[] buff;
return tmp;
}
The use of new/delete is not good style. I could have put it into a try/catch block in case something happened between the two calls.
Nickolay Merkin's and Yuchen Zhong's answers are great, but however from the comments you can see that it is not fully accurate.
The implicit conversion to std::string when printing will wrap the file name in quotations. The comments aren't accurate either.
path::filename()
and path::stem()
returns a new path object and path::string()
returns a reference to a string. Thus something like std::cout << file_path.filename().string() << "\n"
might cause problems with dangling reference since the string that the reference points to might have been destroyed.
'development' 카테고리의 다른 글
목록 정렬 (0) | 2020.11.22 |
---|---|
Eclipse에 Java API 문서를 어떻게 추가합니까? (0) | 2020.11.22 |
자바 스크립트로 미국 전화 번호를 재 형식화하는 정규식 (0) | 2020.11.22 |
스토리 보드의 사용자 지정 글꼴? (0) | 2020.11.22 |
Linux에서 숫자 통계를 인쇄하는 명령 줄 유틸리티 (0) | 2020.11.22 |