从文件名中删除扩展名的简单方法
Easy way to remove extension from a filename?
我正试图从参数中传递的文件名中获取不带扩展名的原始文件名:
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);
}
自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"
然而,这只会删除最后一个文件扩展名:
Was: "/foo/bar.tar.gz"
Now: "/foo/bar.tar"
在我看来,这是最简单、最可读的解决方案:
#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-在茎段发现分解)
BTW也适用于根路径。
以下适用于std::string:
string s = filename;
s.erase(s.find_last_of("."), string::npos);
更复杂,但对于特殊情况(例如:"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;
}
您可以轻松做到这一点:
string fileName = argv[1];
string fileNameWithoutExtension = fileName.substr(0, fileName.rfind("."));
请注意,只有当有一个点时,这才有效。你应该先测试一下是否有点,但你已经明白了。
如果有人只想要一个简单的windows解决方案:
使用PathCchRemoveExtension
->MSDN
或PathRemoveExtension
(已弃用!)->MSDN
尝试以下技巧,从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";
}
只需在列表中循环并替换第一个(或最后一个)出现的'.'带有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] = ' 'l
- 一种在C++中读取TXT配置文件的简单方法
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- CPU 瓶颈;处理具有许多非静态对象的 3D 场景渲染的简单方法
- 在OSX上使用CMake将Adobe的XMP工具包构建为共享库的最简单方法是什么?
- 通过比较C++中的行在 txt 文件中搜索的最简单方法是什么?
- 将时间戳打印到流的最简单方法
- 在C++中创建文件夹选取器对话框的最简单方法是什么?
- C++ 将静态方法转换为简单方法
- 将一系列数字映射到 CPP 中的值的简单方法
- 引用基类模板的成员变量的简单方法
- 学习数据结构和算法的简单方法
- boost::variant - 对变体应用算术的最简单方法
- 创建可以遍历 std::map 值的通用模板迭代器的最简单方法是什么?
- 在C++中将算术类型转换为 std::array 的最简单方法<uint8_t>
- 使用新运算符C++创建多维数组的简单方法
- C++-将ASCII字符数组中可能的数值转换为字符的最简单方法
- OpenSSL模块化最大数据类型大小的简单方法
- 获取当前按键的简单方法
- 多个 if-else 测试的更简单方法
- 为具有多个参数的函数创建 SWIG 类型图的更简单方法?