Normal People Scare Me
Normal People Scare Me

Reputation: 841

Xml Parser - string::find

I am trying to parse a string which contains a line of my XML file.

std::string temp = "<Album>Underclass Hero</Album>";
int f = temp.find(">");
int l = temp.find("</");
std::string _line = temp.substr(f + 1, l-2);

This is a part of my code of my function which should actually return the parsed string. What I expected was that it returns Underclass Hero. Instead I got Underclass Hero< /Alb
(here is between the '<' and '/' a space because I couldn't write them together).

I looked std::string::find several times up and it always said it returns, if existing, the position of the first character of the first match. Here it gives me the last character of the string, but only in my variable l.
f does fine.

link to std::string::find

So can anyone tell me what I'm doing wrong?

Upvotes: 0

Views: 810

Answers (3)

Andreas Florath
Andreas Florath

Reputation: 4612

Don't do it this way!

'Parsing' 'lines' of XML files sooner or later will fail with your attempt. Example: The following is valid XML but your code will fail:

<Album>Underclass Hero<!-- What about </ this --></Album>

P.S.: Please use const where possible:

std::string const temp = ...
// ...
std::string const line = ...

Upvotes: 3

Daniel Frey
Daniel Frey

Reputation: 56921

substr takes the length as the second parameter, not the end position. Try:

temp.substr(f + 1, l-f-1);

Also, please consider using a real XML parser, don't try it yourself or by other inappropriate means.

Upvotes: 5

Andy Prowl
Andy Prowl

Reputation: 126542

The second argument takes the length of the substring you want to extract. You can fix your code this way:

#include <string>
#include <iostream>

int main()
{
    std::string temp = "<Album>Underclass Hero</Album>";
    int f = temp.find(">");
    int l = temp.find("</");
    std::string line = temp.substr(f + 1, l - f - 1);   
    //                                    ^^^^^^^^^
}

Here is a live example.

Also, be careful with names such as _line. Per Paragraph 17.6.4.3.2/1 of the C++11 Standard:

[...] Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.

Upvotes: 5

Related Questions