开发者

string::find returning a value of -1 when it's expected to return a value of 0 [C++]

I have the following code that doesn't work:

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);

When I try to run this code, I get the following error:

terminate called after throwing an instance of 'std::out_of_range'
what():  basic_string::substr
Aborted (core dumped)

I've figured out that this error is occurring because the line.find line is returning a value of -1 to the variable open_tag_start. I can rectify the problem by hard coding a value of 0 into the variable open_tag_start, but I need this to a generic algorithm that will be able to find the tag at any point in the line, so it has to be a variable. Can anyone see what I'm doing wrong here?

Here's some more info.

My goal with this code if to extract a string line_sub from string line, which does indeed contain a string, and when I set size_t open_tag_start = 0, I am able to compile and execute the开发者_StackOverflow code and observe the expected output. line is not empty and my problem is that when I replace

line_sub = line.substr(open_tag_start, open_len);

with

line_sub = line.substr(0, open_len);

my problem goes away and I can compile and execute the code.

This is a short version of my program that contains only the parts that are causing the problems. Attempting to compile this code will yield the error message detailed above. The file rss.xml is the RSS feed for 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);
}


Unless you've left out some code, line is an empty string, so of course find fails. It is your expectation that is in error, not the find function—that's all!

As a side note, you don't need to compensate for '\0' when using C++ strings. Get rid of the + 1.


If the substring isn't found in the string, then the find() method will return std::string::npos, which is a size_type of value -1. When you call substr() with open_tag_start equalling -1, then this is what throws the out_of_range error.


As others have noted, you must check the return value of find() in case the search fails.

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";


Well, are you sure that line contains <image> ?? One thing to consider is that <ImaGe> may be capitalized in some way. Also, i dont quite see what you're trying to do, because line_sub (given that your code works) will just return enter code here and the next character after that. What are you trying to accomplish?

Remember to sanitize your return values. If find returns -1, deal with the problem or throw an error.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜