Bernard
Bernard

Reputation: 4590

How to find position of a substring in string in c++?

I have a string which is coming from command line:

–m –d Tue –t 4 20 –u userid

I save it to a string by this:

string command;
for(int i=1; i<argc;i++){
    string tmp = argv[i];
    command += " "+ tmp + " ";
}

Now I want to manipulate this string to find if there is -u and if there is -u I want to see if the next value is starting with - or is a name. (it can be only -u or -u and a user name. In this example there is a user name)

if(command.find("-u",0)){  
    std::size_t found = command.find_first_of("-u");
    cout<<found<<endl;
}

The output is 14 which is not the right place. My job is to find if there is a -u and if after -u is a user name or nothing or another command starting with -. I appreciate any idea or efficient code.

Edit: I must run this code on another server which I can not take any library instead of built-in g++ libraries.

Upvotes: 0

Views: 2341

Answers (3)

Vlad from Moscow
Vlad from Moscow

Reputation: 311038

Less words more code!:)

#include <iostream>
#include <sstream>
#include <iterator>
#include <algorithm>
#include <string>

int main()
{
    const char *user = "–u";
    std::string s( "–m –d Tue –t 4 20 –u userid" );
    std::string userID;

    std::istringstream is( s );

    auto it = std::find( std::istream_iterator<std::string>( is ),
                         std::istream_iterator<std::string>(),
                         user );

    if ( it != std::istream_iterator<std::string>() )
    {
        ++it;
        if ( it != std::istream_iterator<std::string>() && ( *it )[0] != '-' )
        {
            userID = *it;
        }
    }

    std::cout << "userID = " << userID << std::endl;
}

The output is

userID = userid

Upvotes: -1

Paweł Stawarz
Paweł Stawarz

Reputation: 4012

While there certainly exist many libraries that do the things you want to achieve (see the comments under the question), althought if you want to stick with your code, you have to use string.find instead of string.find_first_of.

find_first_of searches for the first occurence of any character from the first argument (so "-u"). When it finds it, it returns the position, thus in the provided example, it'll return "0" (since –m –d Tue –t 4 20 –u userid starts with -).

If you want to search the string from a given position, you can give find a parameter describing the position it should start from:

size_t find (const string& str, size_t pos = 0) const;

so, if you want to find the first "-" after "-u", you'll do:

// Check if the first thing after "-u" starts with "-":
if(command.find("-u")!=string::npos                                         // if there's an "-u" in the command,
&& (command.find("-",command.find("-u"))                                    // and there's a "-" with a position        
< command.find_first_of("abcdefghijklmnoqprstuwvxys",command.find("-u")))   // less than the position of the first letter after "-u", then:
   cout << "it's a different command";

Upvotes: 2

zoska
zoska

Reputation: 1723

std::string::find_first_of() doesn't work as you expect it to:

Searches the string for the first character that matches any of the characters specified in its arguments.

What you want is std::string::find(), which:

Searches the string for the first occurrence of the sequence specified by its arguments.

But so you wouldn't invent the circle, you should use one of already implemented library of command line options parsing or use included in standard library getopt_long functionality.

Upvotes: 0

Related Questions