tags:

views:

108

answers:

4

For example, lets say I have this string:

"Name, Name2, <b>Name3</b>, Name4, <b>Name5</b>"

I am trying to get whatever value / name is inside the <b> tags. So when I search the char, I get the following in an array:

Name3
Name5

Any ideas? Thanks

+4  A: 

For this type of string searching / matching approach, just use boost regex.

catchmeifyoutry
+1  A: 
start = strstr(s, "<b>")+3;
stop = strstr(start, "</b>");
strncpy(result, start, stop-start);

Don't forget to add error checking.

subsequent matches, for the lazy ones:

s = stop+3;

execute the above code again.

[EDIT] To stop/error checking: check return code of strstr.

Pavel Radzivilovsky
I didn't downvote, but this is tagged C++, not C. Also this only returns one match.
Yacoby
This only works for one match. What if there were multiple matches?
pure841
strstr and strncpy are also available in C++. :)
Jim Buck
How do I stop it once it doesnt find any more matches?
pure841
Downvoted. This is C++, not C, and use of those functions should be absolutely discouraged.
DeadMG
@deadmg, do it with fewer lines in C++, then discourage.
Pavel Radzivilovsky
@DeadMG Wrong, as usual. Upvoted.
anon
There's nothing inherently bad about using these functions, but the way strncpy is used here invites buffer overrun.
Ben Voigt
I agree that you should prefer STL APIs when possible. For instance, fstream is RAII unlike fopen(). I agree that std::string is better than char* in 99% of the cases. But one shouldn't get carried away, and nobody remembers STL syntax anyway.
Pavel Radzivilovsky
Wow, Neil, you just have it in for me. In what circumstances should a C++ developer use buggy, insecure C APIs instead of the more secure and greater functionality offered by STL?
DeadMG
+1  A: 

Here's a basic version using only STL which assumes that the tags are not nested or otherwise misbehaving

#include <iostream>
#include <string>
#include <vector>

int main()
{
    const std::string TAG_OPEN( "<b>" );
    const std::string TAG_CLOSE( "</b>" );
    const std::string s( "Name, Name2, <b>Name3</b>, Name4, <b>Name5</b>" );

    typedef std::vector< std::string > StringArray;
    StringArray tagContents;

    std::string::size_type index = 0;
    while( index != std::string::npos )
    {
        const std::string::size_type o = s.find( TAG_OPEN, index );
        if ( o == std::string::npos )
        {
            break;
        }

        const std::string::size_type c = s.find( TAG_CLOSE, index );
        if ( c == std::string::npos )
        {
            // mismatched tag, ignore?
            break;
        }

        const std::string::size_type tagContentsStart  = o + TAG_OPEN.size();
        const std::string::size_type tagContentsFinish = c;
        tagContents.push_back(
            s.substr( tagContentsStart
                    , tagContentsFinish - tagContentsStart ) );

        index = c + TAG_CLOSE.size();
    }


    for ( StringArray::const_iterator S  = tagContents.begin();
                                      S != tagContents.end();
                                    ++S )
    {
        std::cout << *S << std::endl;
    }

    return 0;
}
Troubadour
Im not working with strings, im working with chars.
pure841
@pure841: Well yes but most, if not all, C++ algorithms will work with some sort of wrapper around raw chars such as `std::string`. If you really only want to work with chars you should probably re-tag the question as C rather than C++.
Troubadour
@pure841: Put your chars into a `std::string`, then use the `std::string` for parsing.
Thomas Matthews
So, you saying its easier to convert the char to string, and then parse it?
pure841
A: 

If you refuse to use std::string and insist on using C-style string, you can always be adventurous and use strtok. It has the feature of modifying your text strings.

Please read up on the side-effects of strtok before using it.

I still strongly suggest making a std::string with your chars, then using the std::string for parsing. There are a lot more features with std::string than with C-style strings.

Thomas Matthews