programing

파일 이름에서 확장자를 제거하는 쉬운 방법?

itsource 2021. 1. 17. 10:52
반응형

파일 이름에서 확장자를 제거하는 쉬운 방법?


인수에 전달 된 파일 이름에서 확장자없이 원시 파일 이름을 가져 오려고합니다.

int main ( int argc, char *argv[] )
{
    // Check to make sure there is a single argument
    if ( argc != 2 )
    {
        cout<<"usage: "<< argv[0] <<" <filename>\n";
        return 1;
    }

    // Remove the extension if it was supplied from argv[1] -- pseudocode
    char* filename = removeExtension(argv[1]);

    cout << filename;

}

예를 들어 "test.dat"를 전달할 때 파일 이름은 "test"여야합니다.


size_t lastindex = fullname.find_last_of("."); 
string rawname = fullname.substr(0, lastindex); 

"."가없는 경우주의하십시오. 그리고 npos를 반환합니다.


이것은 작동합니다 :

std::string remove_extension(const std::string& filename) {
    size_t lastdot = filename.find_last_of(".");
    if (lastdot == std::string::npos) return filename;
    return filename.substr(0, lastdot); 
}

제 생각에는 가장 쉽고 가장 읽기 쉬운 솔루션입니다.

#include <boost/filesystem/convenience.hpp>

std::string removeFileExtension(const std::string& fileName)
{
    return boost::filesystem::change_extension(fileName, "").string();
}

부스트를 좋아하는 사람들을 위해 :

boost :: filesystem :: path :: stem을 사용합니다. 마지막 확장자없이 파일 이름을 반환합니다. 따라서 ./myFiles/foo.bar.foobar는 foo.bar가됩니다. 따라서 하나의 확장 만 처리하고 있다는 것을 알고 있으면 다음을 수행 할 수 있습니다.

boost::filesystem::path path("./myFiles/fileWithOneExt.myExt");
std::string fileNameWithoutExtension = path.stem().string();

여러 확장을 처리해야하는 경우 다음을 수행 할 수 있습니다.

boost::filesystem::path path("./myFiles/fileWithMultiExt.myExt.my2ndExt.my3rdExt");
while(!path.extension().empty())
{
    path = path.stem();
}

std::string fileNameWithoutExtensions = path.stem().string();

(여기에서 가져옴 : http://www.boost.org/doc/libs/1_53_0/libs/filesystem/doc/reference.html#path-decomposition 줄기 섹션에 있음)

BTW는 루트 경로에서도 작동합니다.


다음은 std :: string에서 작동합니다.

string s = filename;
s.erase(s.find_last_of("."), string::npos);

쉽게 할 수 있습니다.

string fileName = argv[1];
string fileNameWithoutExtension = fileName.substr(0, fileName.rfind("."));

점이있는 경우에만 작동합니다. 점이 있는지 먼저 테스트해야하지만 아이디어를 얻을 수 있습니다.


더 복잡하지만 특수한 경우 (예 : "foo.bar/baz", "c : foo.bar", Windows에서도 작동)

std::string remove_extension(const std::string& path) {
    if (path == "." || path == "..")
        return path;

    size_t pos = path.find_last_of("\\/.");
    if (pos != std::string::npos && path[pos] == '.')
        return path.substr(0, pos);

    return path;
}

C ++ 17부터 std :: filesystem :: path :: replace_extension 을 매개 변수와 함께 사용하여 확장을 대체하거나 제거하지 않고 사용할 수 있습니다.

#include <iostream>
#include <filesystem>

int main()
{
    std::filesystem::path p = "/foo/bar.txt";
    std::cout << "Was: " << p << std::endl;
    std::cout << "Now: " << p.replace_extension() << std::endl;
}

다음과 같이 컴파일 하십시오.

g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out

결과 바이너리를 실행하면 다음이 남습니다.

Was: "/foo/bar.txt"
Now: "/foo/bar"

누군가가 Windows에 대한 간단한 솔루션을 원하는 경우 :

사용 PathCchRemoveExtension-> MSDN

... or PathRemoveExtension (deprecated!) ->MSDN


Just loop through the list and replace the first (or last) occurrence of a '.' with a NULL terminator. That will end the string at that point.

Or make a copy of the string up until the '.', but only if you want to return a new copy. Which could get messy since a dynamically allocated string could be a source of memory leak.

for(len=strlen(extension);len>= 0 && extension[len] != '.';len--)
     ;

char * str = malloc(len+1);

for(i=0;i<len;i++)
  str[i] = extension[i];

 str[i] = '\0'l

ReferenceURL : https://stackoverflow.com/questions/6417817/easy-way-to-remove-extension-from-a-filename

반응형