Finding a program argument

Discussion in 'C++' started by Jason Heyes, Apr 9, 2007.

  1. Jason Heyes

    Jason Heyes Guest

    Why can't I use the find algorithm to find a program argument in the
    following way?

    std::find(argv, argv + argc, "-v")

    Thanks.
     
    Jason Heyes, Apr 9, 2007
    #1
    1. Advertising

  2. * Jason Heyes:
    > Why can't I use the find algorithm to find a program argument in the
    > following way?
    >
    > std::find(argv, argv + argc, "-v")
    >
    > Thanks.


    Because you're comparing pointer values.

    To avoid that, do the following:

    #include <algorithm>
    #include <string>
    #include <vector>

    typedef std::vector<std::string> StringVector;

    void cppMain( StringVector const& args )
    {
    if( std::find( args.begin(), args.end(), "-v" ) != args.end() )
    {
    // ...
    }
    }

    int main( int n, char* a[] )
    {
    cppMain( StringVector( a, a + n ) );
    }

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Apr 9, 2007
    #2
    1. Advertising

  3. Jason Heyes

    Salt_Peter Guest

    On Apr 9, 3:15 am, "Jason Heyes" <> wrote:
    > Why can't I use the find algorithm to find a program argument in the
    > following way?
    >
    > std::find(argv, argv + argc, "-v")
    >
    > Thanks.


    argv is an array of pointers (char*), not an array of strings
    try loading the parameters in a container and then iterate through it.
    A std::vector of std::string is perfect for the job.

    int main(int argc, char* argv[])
    {
    std::vector<std::string> vs;
    for(int n = 0; n < argc; ++n)
    {
    std::cout << "argument " << n;
    std::cout << " is ";
    std::cout << argv[n] << std::endl;
    vs.push_back(argv[n]);
    }

    typedef std::vector<std::string>::iterator VIter;
    VIter viter = std::find(vs.begin(), vs.end(), "-v");
    if(viter != vs.end())
    {
    std::cout << "parameter -v found\n";
    } else {
    std::cout << "parameter not found\n";
    }

    return 0;
    }

    /*
    argument 0 is ./proj_test
    argument 1 is -a
    argument 2 is -b
    argument 3 is -v
    parameter -v found
    */
     
    Salt_Peter, Apr 9, 2007
    #3
  4. Alf P. Steinbach wrote:
    ....
    > To avoid that, do the following:
    >
    > #include <algorithm>
    > #include <string>
    > #include <vector>
    >
    > typedef std::vector<std::string> StringVector;
    >
    > void cppMain( StringVector const& args )
    > {
    > if( std::find( args.begin(), args.end(), "-v" ) != args.end() )
    > {
    > // ...
    > }
    > }
    >
    > int main( int n, char* a[] )
    > {
    > cppMain( StringVector( a, a + n ) );
    > }
    >


    That technique does not work so well if you have an argument value that
    is "-v".
     
    Gianni Mariani, Apr 9, 2007
    #4
  5. Jason Heyes

    Pete Becker Guest

    Jason Heyes wrote:
    > Why can't I use the find algorithm to find a program argument in the
    > following way?
    >
    > std::find(argv, argv + argc, "-v")
    >


    You're dealing here with char*'s, and by default std::find compares the
    addresses that they hold. Since you need to compare the C-style strings
    that they point to, you have to provide a predicate that does that, and
    use find_if:

    struct cmp
    {
    cmp(const char *str) : tgt(str) {}
    const char *tgt;
    bool operator()(const char *s)
    {
    return strcmp(tgt, s) == 0;
    }
    };

    std::find_if(argv, argv + argc, cmp("-v"));

    --

    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com)
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." (www.petebecker.com/tr1book)
     
    Pete Becker, Apr 9, 2007
    #5
  6. * Gianni Mariani:
    > Alf P. Steinbach wrote:
    > ...
    >> To avoid that, do the following:
    >>
    >> #include <algorithm>
    >> #include <string>
    >> #include <vector>
    >>
    >> typedef std::vector<std::string> StringVector;
    >>
    >> void cppMain( StringVector const& args )
    >> {
    >> if( std::find( args.begin(), args.end(), "-v" ) != args.end() )
    >> {
    >> // ...
    >> }
    >> }
    >>
    >> int main( int n, char* a[] )
    >> {
    >> cppMain( StringVector( a, a + n ) );
    >> }
    >>

    >
    > That technique does not work so well if you have an argument value that
    > is "-v".


    What do you mean?

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Apr 9, 2007
    #6
  7. Jason Heyes

    Fei Liu Guest

    Alf P. Steinbach wrote:
    > * Gianni Mariani:
    >> Alf P. Steinbach wrote:
    >> ...
    >>> To avoid that, do the following:
    >>>
    >>> #include <algorithm>
    >>> #include <string>
    >>> #include <vector>
    >>>
    >>> typedef std::vector<std::string> StringVector;
    >>>
    >>> void cppMain( StringVector const& args )
    >>> {
    >>> if( std::find( args.begin(), args.end(), "-v" ) != args.end() )
    >>> {
    >>> // ...
    >>> }
    >>> }
    >>>
    >>> int main( int n, char* a[] )
    >>> {
    >>> cppMain( StringVector( a, a + n ) );
    >>> }
    >>>

    >>
    >> That technique does not work so well if you have an argument value
    >> that is "-v".

    >
    > What do you mean?
    >


    I think he's trying to say something like this
    prog -option -v where '-v' is argument value to an argument option.
     
    Fei Liu, Apr 9, 2007
    #7
  8. Jason Heyes

    Marcus Kwok Guest

    Salt_Peter <> wrote:
    > argv is an array of pointers (char*), not an array of strings
    > try loading the parameters in a container and then iterate through it.
    > A std::vector of std::string is perfect for the job.
    >
    > int main(int argc, char* argv[])
    > {
    > std::vector<std::string> vs;
    > for(int n = 0; n < argc; ++n)
    > {
    > std::cout << "argument " << n;
    > std::cout << " is ";
    > std::cout << argv[n] << std::endl;
    > vs.push_back(argv[n]);
    > }


    Personally, I would initialize the string vector instead of building it
    incrementally:

    std::vector<std::string> vs(argv, argv + argc);

    --
    Marcus Kwok
    Replace 'invalid' with 'net' to reply
     
    Marcus Kwok, Apr 11, 2007
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bhushit Joshipura

    defaulting argument to previous argument

    Bhushit Joshipura, Dec 29, 2003, in forum: C++
    Replies:
    5
    Views:
    416
  2. Ben Kial
    Replies:
    1
    Views:
    664
    Eric Enright
    Nov 15, 2004
  3. S?ren Gammelmark
    Replies:
    1
    Views:
    1,899
    Eric Sosman
    Jan 7, 2005
  4. nw
    Replies:
    0
    Views:
    316
  5. Reckoner
    Replies:
    11
    Views:
    708
    Steven D'Aprano
    Jan 19, 2009
Loading...

Share This Page