获取扩展名std :: out_of_range错误

时间:2016-05-19 13:50:23

标签: c++

这段代码有什么问题?还有另一种方法吗? 它一直在抛出std :: out_of_range错误。

std::wstring ext(FileInformation.cFileName);
ext = ext.substr(ext.find(L"."));

3 个答案:

答案 0 :(得分:3)

错误的是你没有处理文件没有扩展名的情况。

ext.find(L".") returns std::wstring::npos(最高可能的数字 - 表示"未找到")会发生什么,因为它找不到点。

然后您正在调用ext.substr(std::wstring::npos),这当然超出了范围。

您必须检查此案例:

std::wstring ext(FileInformation.cFileName);
std::size_t dotPos = ext.find(L".");
if(dotPos != std::wstring::npos) {
    ext = ext.substr(dotPos);
} else {
    ext = L"."; // assuming you want to treat an empty extension like this
}

但是,如果你的目标是提取文件扩展名,那么还需要注意一些问题:

  • Windows仅将最后一个点后面的部分视为文件扩展名。您的代码将为名为.a.b的文件提供file.a.b,而Windows会将文件扩展名视为.b。因此,您可能需要使用rfind代替find,后者会向后搜索。
  • 但是还有另一个细微之处:文件扩展名不能包含空格(file.hello world是一个没有扩展名的文件),所以你需要检查一下......

因此,由于您显然已经在使用WinAPI,我建议您使用为此目的而制作的WinAPI函数:PathFindExtension。这样,你就不会弄错。

示例(假设您仍然想要一个点 - 否则删除它):

ext = std::wstring(L".") + *PathFindExtension(ext.c_str());

或者,也会有boost库,它也可以使用boost::path::extension提取文件扩展名,但它有点重,如果你还没有使用boost,不值得考虑。

答案 1 :(得分:1)

没有“。” FileInformation.cFileNamefind将返回std::wstring::npos,因此请先检查find的返回情况,然后致电substr

也许是这样的:

std::wstring ext(FileInformation.cFileName);
std::size_t found=ext.find(L".");
if (found!=std::wstring::npos)
    ext = ext.substr(found);

答案 2 :(得分:1)

FileInformation.cFileName没有包含点,然后find()将返回string :: npos。

因此,如果substr的第一个参数大于字符串长度,则首先需要使用substr cause来检查string :: npos,它会抛出out_of_range。