我有以下代码不起作用:
string line;
string line_sub;
size_t open_tag_start;
const string open_tag = "<image>";
const int open_len = open_tag.length() + 1;
open_tag_start = line.find(open_tag);
line_sub = line.substr(open_tag_start, open_len);
当我尝试运行此代码时,出现以下错误:
terminate called after throwing an instance of 'std::out_of_range' what(): basic_string::substr Aborted (core dumped)
我发现发生此错误是因为line.find
行将值-1
返回给变量open_tag_start
。我可以通过将0
的值硬编码到变量open_tag_start
中来解决问题,但我需要这个能够在行中的任何位置找到标记的通用算法,所以它必须是一个变量。谁能看到我在这里做错了什么?
以下是更多信息。
我的目标是使用此代码从string line_sub
中提取string line
,确实包含字符串,当我设置size_t open_tag_start = 0
时,我能够编译并执行代码并观察预期的输出。 line
不是空的,我的问题是当我更换
line_sub = line.substr(open_tag_start, open_len);
带
line_sub = line.substr(0, open_len);
我的问题消失了,我可以编译并执行代码。
这是我的程序的简短版本,仅包含导致问题的部分。尝试编译此代码将产生上面详述的错误消息。文件rss.xml
是engadget.com http://www.engadget.com/rss.xml
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <cstring>
using namespace std;
void get_tag_contents(ifstream& rssfile, string line, string open_tag);
int main()
{
const string open_tag = "<image>";
ifstream rssfile;
rssfile.open("rss.xml");
string line;
getline(rssfile, line, '\n');
get_tag_contents(rssfile, line, open_tag);
return 0;
}
void get_tag_contents(ifstream& rssfile, string line, string open_tag)
{
const int open_len = open_tag.length() + 1;
size_t open_tag_start;
string line_sub;
open_tag_start = line.find(open_tag);
line_sub = line.substr(open_tag_start, open_len);
}
答案 0 :(得分:3)
除非你遗漏了一些代码,line
是一个空字符串,所以当然find
失败了。你的期望是错误的,而不是find
函数 - 这就是全部!
作为旁注,在使用C ++字符串时,您无需补偿'\0'
。摆脱+ 1
。
答案 1 :(得分:2)
如果在字符串中找不到子字符串,则find()
方法将返回std::string::npos
,这是一个值为-1的size_type。当您使用substr()
等于-1来调用open_tag_start
时,这就是抛出out_of_range错误的原因。
答案 2 :(得分:1)
正如其他人所说,如果搜索失败,你必须检查find()的返回值。
std::string line("this is <image> a test");
std::string line_sub;
const std::string open_tag = "<image>";
size_t open_tag_start = line.find(open_tag);
if (open_tag_start != std::string::npos)
{
line_sub = line.substr(open_tag_start, open_tag.length());
}
std::cout << line << "\n" << line_sub << "\n";
答案 3 :(得分:0)
嗯,你确定line
包含<image>
吗?需要考虑的一件事是<ImaGe>
可能以某种方式大写。此外,我不太明白你要做什么,因为line_sub
(假设你的代码有效)将只返回enter code here
和之后的下一个字符。你想要完成什么?
请记住清理您的返回值。如果find返回-1,则处理问题或抛出错误。