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

时间:2011-06-20 21:33:17

标签: 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;

}

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

11 个答案:

答案 0 :(得分:74)

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

当没有“。”时要小心。并返回npos

答案 1 :(得分: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); 
}

答案 2 :(得分:14)

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

#include <boost/filesystem/convenience.hpp>

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

答案 3 :(得分:11)

对于那些喜欢激励的人:

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

ü

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

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

(取自这里:在茎部分找到的http://www.boost.org/doc/libs/1_53_0/libs/filesystem/doc/reference.html#path-decomposition

BTW也适用于有根路径。

答案 4 :(得分:10)

以下适用于std :: string:

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

答案 5 :(得分:2)

您可以轻松完成此操作:

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

请注意,这只适用于有点的情况。如果有点,你应该先测试一下,但是你明白了。

答案 6 :(得分:1)

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

使用PathCchRemoveExtension - &gt; MSDN

...或PathRemoveExtension(已弃用!) - &gt; MSDN

答案 7 :(得分:1)

更复杂,但就特殊情况而言(例如:&#34; foo.bar/baz" ;,&#34; c:foo.bar&#34;,也适用于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;
}

答案 8 :(得分:0)

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

Compile与:

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

运行生成的二进制文件会使您:

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

答案 9 :(得分:0)

尝试以下技巧,从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";
}

答案 10 :(得分:-2)

只需遍历列表并替换'。'的第一个(或最后一个)事件。使用NULL终止符。那将在那时结束字符串。

或者将字符串的副本复制到'。',但仅当您要返回新副本时。由于动态分配的字符串可能是内存泄漏的来源,因此可能会变得混乱。

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
相关问题