C++ 如何从C++中的字符串获取文件扩展名
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/51949/
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
How to get file extension from string in C++
提问by JeffV
Given a string "filename.conf"
, how to I verify the extension part?
给定一个字符串"filename.conf"
,如何验证扩展部分?
I need a cross platform solution.
我需要一个跨平台的解决方案。
采纳答案by Torlack
You have to make sure you take care of file names with more then one dot.
example: c:\.directoryname\file.name.with.too.many.dots.ext
would not be handled correctly by strchr
or find.
您必须确保处理包含多个点的文件名。例如:c:\.directoryname\file.name.with.too.many.dots.ext
不会被strchr
或正确处理find.
My favorite would be the boost filesystem librarythat have an extension(path) function
我最喜欢的是具有扩展(路径)功能的boost 文件系统库
回答by brian newman
Is this too simple of a solution?
这是不是太简单的解决方案?
#include <iostream>
#include <string>
int main()
{
std::string fn = "filename.conf";
if(fn.substr(fn.find_last_of(".") + 1) == "conf") {
std::cout << "Yes..." << std::endl;
} else {
std::cout << "No..." << std::endl;
}
}
回答by Torlack
The best way is to not write any code that does it but call existing methods. In windows, the PathFindExtensionmethod is probably the simplest.
最好的方法是不编写任何执行此操作的代码,而是调用现有方法。在 Windows 中,PathFindExtension方法可能是最简单的。
So why would you not write your own?
那你为什么不自己写呢?
Well, take the strrchr example, what happens when you use that method on the following string "c:\program files\AppleGate.Net\readme"? Is ".Net\readme" the extension? It is easy to write something that works for a few example cases, but can be much harder to write something that works for all cases.
好吧,以 strrchr 为例,当您在以下字符串“c:\program files\AppleGate.Net\readme”上使用该方法时会发生什么?“.Net\readme”是扩展名吗?编写适用于一些示例案例的内容很容易,但编写适用于所有案例的内容可能要困难得多。
回答by 17 of 26
Assuming you have access to STL:
假设您可以访问 STL:
std::string filename("filename.conf");
std::string::size_type idx;
idx = filename.rfind('.');
if(idx != std::string::npos)
{
std::string extension = filename.substr(idx+1);
}
else
{
// No extension found
}
Edit:This is a cross platform solution since you didn't mention the platform. If you're specifically on Windows, you'll want to leverage the Windows specific functions mentioned by others in the thread.
编辑:这是一个跨平台解决方案,因为您没有提到平台。如果您专门使用 Windows,您将希望利用线程中其他人提到的 Windows 特定功能。
回答by peter karasev
Someone else mentioned boost but I just wanted to add the actual code to do this:
其他人提到了提升,但我只是想添加实际代码来做到这一点:
#include <boost/filesystem.hpp>
using std::string;
string texture = foo->GetTextureFilename();
string file_extension = boost::filesystem::extension(texture);
cout << "attempting load texture named " << texture
<< " whose extensions seems to be "
<< file_extension << endl;
// Use JPEG or PNG loader function, or report invalid extension
回答by graphitemaster
actually the STL can do this without much code, I advise you learn a bit about the STL because it lets you do some fancy things, anyways this is what I use.
实际上 STL 可以在没有太多代码的情况下做到这一点,我建议您了解一下 STL,因为它可以让您做一些花哨的事情,无论如何这就是我使用的。
std::string GetFileExtension(const std::string& FileName)
{
if(FileName.find_last_of(".") != std::string::npos)
return FileName.substr(FileName.find_last_of(".")+1);
return "";
}
this solution will always return the extension even on strings like "this.a.b.c.d.e.s.mp3" if it cannot find the extension it will return "".
此解决方案将始终返回扩展名,即使是“this.abcdesmp3”这样的字符串,如果找不到扩展名,它将返回“”。
回答by Roi Danton
With C++17 and its std::filesystem::path::extension
(the library is the successor to boost::filesystem) you would make your statement more expressive than using e.g. std::string
.
使用 C++17 及其std::filesystem::path::extension
(该库是 boost::filesystem 的继承者),您将使您的语句比使用 eg 更具表现力std::string
。
#include <iostream>
#include <filesystem> // C++17
namespace fs = std::filesystem;
int main()
{
fs::path filePath = "my/path/to/myFile.conf";
if (filePath.extension() == ".conf") // Heed the dot.
{
std::cout << filePath.stem() << " is a valid type."; // Output: "myFile is a valid type."
}
else
{
std::cout << filePath.filename() << " is an invalid type."; // Output: e.g. "myFile.cfg is an invalid type"
}
}
See also std::filesystem::path::stem, std::filesystem::path::filename.
另见std::filesystem::path::stem、std::filesystem::path::filename。
回答by Qiu
Actually, the easiest way is
其实最简单的方法就是
char* ext;
ext = strrchr(filename,'.')
One thing to remember: if '.'
doesn't exist in filename, ext will be NULL
.
要记住的一件事:如果'.'
文件名中不存在,则 ext 将是NULL
.
回答by serengeor
I've stumbled onto this question today myself, even though I already had a working code I figured out that it wouldn't work in some cases.
今天我自己偶然发现了这个问题,尽管我已经有了一个工作代码,但我发现它在某些情况下不起作用。
While some people already suggested using some external libraries, I prefer to write my own code for learning purposes.
虽然有些人已经建议使用一些外部库,但我更喜欢编写自己的代码以供学习。
Some answers included the method I was using in the first place (looking for the last "."), but I remembered that on linux hidden files/folders start with ".". So if file file is hidden and has no extension, the whole file name would be taken for extension. To avoid that I wrote this piece of code:
一些答案包括我首先使用的方法(寻找最后一个“.”),但我记得在 linux 上隐藏文件/文件夹以“.”开头。因此,如果文件 file 被隐藏且没有扩展名,则将使用整个文件名作为扩展名。为了避免这种情况,我写了这段代码:
bool getFileExtension(const char * dir_separator, const std::string & file, std::string & ext)
{
std::size_t ext_pos = file.rfind(".");
std::size_t dir_pos = file.rfind(dir_separator);
if(ext_pos>dir_pos+1)
{
ext.append(file.begin()+ext_pos,file.end());
return true;
}
return false;
}
I haven't tested this fully, but I think that it should work.
我还没有完全测试过,但我认为它应该可以工作。
回答by KristianR
Using std::string's find/rfind solves THIS problem, but if you work a lot with paths then you should look at boost::filesystem::path since it will make your code much cleaner than fiddling with raw string indexes/iterators.
使用 std::string 的 find/rfind 解决了这个问题,但是如果你经常使用路径,那么你应该看看 boost::filesystem::path ,因为它会让你的代码比摆弄原始字符串索引/迭代器更干净。
I suggest boost since it's a high quality, well tested, (open source and commercially) free and fully portable library.
我建议使用 boost,因为它是一个高质量、经过良好测试、(开源和商业)免费且完全可移植的库。