C++ 从文件名中删除扩展名的简单方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6417817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 20:06:02  来源:igfitidea点击:

Easy way to remove extension from a filename?

c++

提问by Flarmar Brunjd

I am trying to grab the raw filename without the extension from the filename passed in arguments:

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

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;

}

The filename should for example be "test" when I passed in "test.dat".

例如,当我传入“test.dat”时,文件名应该是“test”。

回答by Adithya Surampudi

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

Beware of the case when there is no "." and it returns npos

小心没有“.”的情况。它返回 npos

回答by orlp

This works:

这有效:

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); 
}

回答by baziorek

In my opinion it is easiest, and the most readable solution:

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

#include <boost/filesystem/convenience.hpp>

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

回答by anhoppe

For those who like boost:

对于喜欢boost的人:

Use boost::filesystem::path::stem. It returns the filename without the last extension. So ./myFiles/foo.bar.foobar becomes foo.bar. So when you knowyou are dealing with only one extension you could do the follwing:

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

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

When you have to deal with multiple extensions you might do the following:

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

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

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

(taken from here: http://www.boost.org/doc/libs/1_53_0/libs/filesystem/doc/reference.html#path-decompositionfound in the stem section)

(取自此处:http: //www.boost.org/doc/libs/1_53_0/libs/filesystem/doc/reference.html#path-decomposition在词干部分找到)

BTW works with rooted paths, too.

顺便说一句,也适用于根路径。

回答by Shiroko

The following works for a std::string:

以下适用于 std::string:

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

回答by Phidelux

Since C++17 you can use std::filesystem::path::replace_extensionwith a parameter to replace the extension or without to remove it:

从 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;
}

Compileit with:

编译它:

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

Running the resulting binary leaves you with:

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

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

回答by Baptiste Wicht

You can do this easily :

你可以很容易地做到这一点:

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

Note that this only work if there is a dot. You should test before if there is a dot, but you get the idea.

请注意,这仅在有点时才有效。如果有一个点,你应该先测试一下,但你明白了。

回答by Vladimir Gamalyan

More complex, but with respect to special cases (for example: "foo.bar/baz", "c:foo.bar", works for Windows too)

更复杂,但对于特殊情况(例如:“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;
}

回答by Lars Fr?lich

In case someone just wants a simple solution for windows:

如果有人只是想要一个简单的 Windows 解决方案:

Use PathCchRemoveExtension->MSDN

使用PathCchRemoveExtension-> MSDN

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

...或PathRemoveExtension(已弃用!)-> MSDN

回答by Aymen Alsaadi

Try the following trick to extract the file name from path with no extension in c++ with no external libraries in c++ :

尝试使用以下技巧从 c++ 中没有扩展名且 c++ 中没有外部库的路径中提取文件名:

#include <iostream>
#include <string>

using std::string;

string getFileName(const string& s) {
char sep = '/';
#ifdef _WIN32
sep = '\';
#endif
size_t i = s.rfind(sep, s.length());
if (i != string::npos) 
{
  string filename = s.substr(i+1, s.length() - i);
  size_t lastindex = filename.find_last_of("."); 
  string rawname = filename.substr(0, lastindex); 
  return(rawname);
}

return("");
}

int main(int argc, char** argv) {

string path = "/home/aymen/hello_world.cpp";
string ss = getFileName(path);
std::cout << "The file name is \"" << ss << "\"\n";
}