경로에서 파일 이름을 추출하는 방법
Linux API/POSIX에는 전체 경로에서 기본 파일 이름을 추출하는 우아한 것이 있어야 합니다.
참조.
"는을 " 명령실니다합행또▁"▁command다▁the" 을 실행합니다.man 3 basename대상 UNIX/POSIX 시스템에서 사용할 수 있습니다.
사용하다basename(의미를 ) strrchr(pathname, '/')전체 문자열이 다음을 포함하지 않는 경우 기본 이름으로 처리합니다.'/'성격.
다음은 1-라인의 예입니다( 주어진).char * whoami는 기본 알고리즘을 것입니다.
(whoami = strrchr(argv[0], '/')) ? ++whoami : (whoami = argv[0]);
NULL이 가능한 경우 추가 확인이 필요합니다.또한 이것은 원래 문자열을 가리킬 뿐입니다. -- a "strdup()적합할 수 있습니다.
사용할 수 있습니다.strstr디렉터리 이름에도 관심이 있는 경우:
char *path ="ab/cde/fg.out";
char *ssc;
int l = 0;
ssc = strstr(path, "/");
do{
l = strlen(ssc) + 1;
path = &path[strlen(path)-l+2];
ssc = strstr(path, "/");
}while(ssc);
printf("%s\n", path);
그basename()function은 파일 이름이 아닌 폴더 이름일 수 있는 경로의 마지막 구성 요소를 반환합니다.의 두 가지 버전이 있습니다.basename()함수: GNU 버전과 POSIX 버전.
은 GNU 버전다확수있습에서 찾을 수 .string.h를 한 후#define _GNU_SOURCE:
#정의 _GNU_SOURCE #filen < string.h>
은 GNU 버전사용다니합음을 사용합니다.const인수를 수정하지 않습니다.
char * 기본 이름(constchar *path)
이 은 "XPG(POSIX)"가 "XPG(POSIX)"일 경우 ) 됩니다.libgen.h포함됩니다.
char * 기본 이름(char *path)
이 함수는 뒤에 오는 '/'바이트를 제거하여 인수를 수정할 수 있습니다.이 경우 결과는 GNU 버전과 다를 수 있습니다.
기본 이름("foo/bar/")
XPG 버전을 사용하는 경우 문자열 "bar"를 반환하고 GNU 버전을 사용하는 경우 빈 문자열을 반환합니다.
참조:
-
base name (3) - 리눅스 맨 페이지
-
함수: char * basname(constchar * filename), 문자열에서 토큰 찾기.
물론 이것이 Gnu/Linux만의 질문이라면 라이브러리 기능을 사용할 수 있습니다.
https://linux.die.net/man/3/basename
그리고 일부는 이러한 POSIX 호환 Gnu Library 함수를 거부할 수 있지만 const를 사용하지 않습니다.라이브러리 유틸리티 기능은 거의 수행되지 않습니다.만약 그것이 당신에게 중요하다면, 당신은 당신 자신의 기능을 고수해야 할 것입니다. 아니면 다음과 같은 것들이 당신의 취향에 더 맞을까요?
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *fn;
char *input;
if (argc > 1)
input = argv[1];
else
input = argv[0];
/* handle trailing '/' e.g.
input == "/home/me/myprogram/" */
if (input[(strlen(input) - 1)] == '/')
input[(strlen(input) - 1)] = '\0';
(fn = strrchr(input, '/')) ? ++fn : (fn = input);
printf("%s\n", fn);
return 0;
}
template<typename charType>
charType* getFileNameFromPath( charType* path )
{
if( path == NULL )
return NULL;
charType * pFileName = path;
for( charType * pCur = path; *pCur != '\0'; pCur++)
{
if( *pCur == '/' || *pCur == '\\' )
pFileName = pCur+1;
}
return pFileName;
}
호출: wchar_t * fileName = getFileNameFromPath < wchar_t > (filePath );
(이것은 c++입니다)
슬래시를 백슬래시로 이스케이프하고 다음 코드를 사용할 수 있습니다.
#include <stdio.h>
#include <string.h>
int main(void)
{
char path[] = "C:\\etc\\passwd.c"; //string with escaped slashes
char temp[256]; //result here
char *ch; //define this
ch = strtok(path, "\\"); //first split
while (ch != NULL) {
strcpy(temp, ch);//copy result
printf("%s\n", ch);
ch = strtok(NULL, "\\");//next split
}
printf("last filename: %s", temp);//result filename
return 0;
}
경로의 파일 이름이나 마지막 부분만 가져오는 더 간단한 방법을 사용했습니다.
char * extract_file_name(char *path)
{
int len = strlen(path);
int flag=0;
printf("\nlength of %s : %d",path, len);
for(int i=len-1; i>0; i--)
{
if(path[i]=='\\' || path[i]=='//' || path[i]=='/' )
{
flag=1;
path = path+i+1;
break;
}
}
return path;
}
Input path = "C:/Users/me/Documents/somefile.txt"
Output = "somefile.txt"
@Nikolay Khilyuk은 다음을 제외하고 가장 좋은 해결책을 제공합니다.
char*를 사용하는 것으로 돌아가십시오. const를 사용하는 것에 대한 좋은 이유는 절대 없습니다.
이 코드는 이식 가능하지 않으며 컴파일러 구현에 따라 /가 파일 시스템 구분 기호가 아닌 POSIX 시스템에서는 실패할 가능성이 높습니다.일부 윈도우즈 컴파일러의 경우 '/' 대신 '\'을 테스트할 수 있습니다.시스템을 테스트하고 결과에 따라 구분 기호를 설정할 수도 있습니다.
함수 이름은 길지만 설명이 가능하며 문제가 없습니다.함수가 파일 이름을 반환하는지 확인할 수 있는 방법은 없습니다. 함수가 올바르게 코드화된 경우에만 파일 이름이 반환되는지 확인할 수 있습니다.하지만 누군가가 경로가 아닌 문자열에서 사용하면 분명히 실패할 것입니다.저는 아마 그것의 목적이 무엇인지 많은 프로그래머들에게 전달할 것이기 때문에 그것의 기본 이름을 붙였을 것입니다.그것은 단지 내가 선호하는 것일 뿐이지만, 내 편견에 따르면 당신의 이름은 괜찮습니다.이 함수가 처리할 문자열의 길이와 왜 그것이 포인트가 될 것이라고 생각한 사람이 있습니까?이 함수가 ANSIC 컴파일러에서 처리할 수 있는 경로 이름보다 긴 경로 이름을 처리할 가능성은 거의 없습니다.as size_t는 0 ~ 4,294,967,295 범위의 부호 없는 긴 int로 정의됩니다.
저는 다음과 같이 당신의 기능을 증명했습니다.
#include <stdio.h>
#include <string.h>
char* getFileNameFromPath(char* path);
int main(int argc, char *argv[])
{
char *fn;
fn = getFileNameFromPath(argv[0]);
printf("%s\n", fn);
return 0;
}
char* getFileNameFromPath(char* path)
{
for(size_t i = strlen(path) - 1; i; i--)
{
if (path[i] == '/')
{
return &path[i+1];
}
}
return path;
}
Daniel Kamil Kozar가 위에서 수정한 1 off 오류를 발견했지만 잘 작동했습니다.이 오류는 잘못된 형식의 절대 경로로만 표시되지만 이 함수는 가짜 입력을 처리할 수 있어야 합니다.당신을 비판하는 모든 사람의 말을 듣지 마세요.어떤 사람들은 의견이 가치가 없을 때에도 의견을 갖는 것을 좋아합니다.
strstr() 솔루션은 파일 이름이 경로의 디렉터리 이름과 동일하고 특히 실행 파일에 확장자가 없는 POSIX 시스템에서 발생할 수 있고 발생할 수 있는 경우 실패하기 때문에 좋아하지 않습니다.적어도 처음에는 여러 테스트를 수행해야 하며 strstr()로 구분 기호를 검색하면 구분 기호가 몇 개 있는지 알 수 없기 때문에 훨씬 더 번거롭습니다.만약 당신이 왜 사람들이 실행 가능한 sink busybox의 기본 이름을 원하는지 궁금하다면, egrep, fgrep 등.
strrchar()는 문자열이 아닌 문자를 검색하기 때문에 구현하기가 번거로울 수 있으므로 이 솔루션만큼 실행 가능하거나 단순하지 않습니다.나는 래드 렉서스에 의해 이것이 내가 생각했던 것만큼 번거롭지 않을 것이라고 정정합니다. strchar()는 발견된 문자를 넘어 문자열의 색인을 반환하는 부작용이 있기 때문입니다.
몸조심하세요.
예(향상됨):
#include <string.h>
const char* getFileNameFromPath(const char* path, char separator = '/')
{
if(path != nullptr)
{
for(size_t i = strlen(path); i > 0; --i)
{
if (path[i-1] == separator)
{
return &path[i];
}
}
}
return path;
}
언급URL : https://stackoverflow.com/questions/7180293/how-to-extract-filename-from-path
'programing' 카테고리의 다른 글
| "를 해결하는 방법은 'esModule'을 사용해야만 기본값으로 가져올 수 있습니다.비주얼 스튜디오 2019에서 인터옵' 플래그? (0) | 2023.07.07 |
|---|---|
| JasperReport를 여러 워크시트가 있는 Excel 파일로 내보내려면 어떻게 해야 합니까? (0) | 2023.07.07 |
| Spring Security 헤더를 사용하지 않도록 설정해도 작동하지 않음 (0) | 2023.07.07 |
| 데이터 프레임에 열이 있는지 여부를 확인하는 방법 (0) | 2023.07.07 |
| Oracle용 MyBatis 배치 삽입/업데이트 (0) | 2023.07.07 |