从文件名中删除扩展名的简便方法?

Fla*_*njd 55 c++

我试图从参数传递的文件名中获取没有扩展名的原始文件名:

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;

}
Run Code Online (Sandbox Code Playgroud)

例如,当我传入"test.dat"时,文件名应为"test".

小智 80

size_t lastindex = fullname.find_last_of("."); 
string rawname = fullname.substr(0, lastindex); 
Run Code Online (Sandbox Code Playgroud)

当没有"."时要小心.它返回npos

  • 很抱歉给这样一个旧答案添加注释,但`substr`的​​第二个参数的默认值是`npos`,所以你不必担心`find_last_of`返回`npos`,你可以简单地做:`rawname = fullname.substr(0,fullname.find_last_of("."));` (15认同)
  • 有时目录可以包含"." 例如:projects/Name.Surname/binary在这种情况下代码将返回:projects/Name (3认同)
  • 警告:除了Grzegorz正确的评论,如果文件名以"."开头,这也应该"失败"(不是预期的结果).并且没有延期. (2认同)

orl*_*rlp 29

这有效:

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); 
}
Run Code Online (Sandbox Code Playgroud)


baz*_*rek 16

在我看来,这是最简单,最易读的解决方案:

#include <boost/filesystem/convenience.hpp>

std::string removeFileExtension(const std::string& fileName)
{
    return boost::filesystem::change_extension(fileName, "").string();
}
Run Code Online (Sandbox Code Playgroud)

  • 这段代码为示例路径“ projects / Name.Surname / binary”给出了正确的结果,对于该示例路径,“接受的答案”失败**(以及所有其他的`fileName.substr(0,fileName.find_last_of(“)变体。 “))。请参阅[Coliru上的实时演示](http://coliru.stacked-crooked.com/a/c0ab50cb9c667877)。 (5认同)
  • 我想大多数人会不同意你的意见 (3认同)

Phi*_*lux 15

从 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;
}
Run Code Online (Sandbox Code Playgroud)

编译它:

g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
Run Code Online (Sandbox Code Playgroud)

运行生成的二进制文件会给你带来:

Was: "/foo/bar.txt"
Now: "/foo/bar"
Run Code Online (Sandbox Code Playgroud)

但是,这只会删除最后一个文件扩展名:

Was: "/foo/bar.tar.gz"
Now: "/foo/bar.tar"
Run Code Online (Sandbox Code Playgroud)


anh*_*ppe 11

对于那些喜欢激励的人:

使用boost :: filesystem :: path :: stem.它返回没有最后一个扩展名的文件名.所以./myFiles/foo.bar.foobar变成了foo.bar.所以当你知道的时候您只处理一个扩展时,您可以执行以下操作:

boost::filesystem::path path("./myFiles/fileWithOneExt.myExt");
std::string fileNameWithoutExtension = path.stem().string();
Run Code Online (Sandbox Code Playgroud)

当您必须处理多个扩展时,您可能会执行以下操作:

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

std::string fileNameWithoutExtensions = path.stem().string();
Run Code Online (Sandbox Code Playgroud)

(取自这里:http://www.boost.org/doc/libs/1_53_0/libs/filesystem/doc/reference.html#path-decomposition in stem section)

BTW也适用于根路径.


Shi*_*oko 10

以下适用于std :: string:

string s = filename;
s.erase(s.find_last_of("."), string::npos);
Run Code Online (Sandbox Code Playgroud)

  • 对于“项目/名称。姓氏/二进制”失败。 (2认同)

Vla*_*yan 5

更复杂,但针对特殊情况(例如:“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;
}
Run Code Online (Sandbox Code Playgroud)