need help with string

Discussion in 'C++' started by puzzlecracker, Oct 17, 2005.

  1. let's say have a string: string str="arg1 arg2 arg3";

    I need to convert it to

    char **s where s={arg1, arg2,arg3, NULL};


    has anyone encountered this problem and has fast solution?

    Thanks
     
    puzzlecracker, Oct 17, 2005
    #1
    1. Advertising

  2. puzzlecracker wrote:
    > let's say have a string: string str="arg1 arg2 arg3";
    >
    > I need to convert it to
    >
    > char **s where s={arg1, arg2,arg3, NULL};
    >
    >
    > has anyone encountered this problem and has fast solution?
    >
    > Thanks
    >


    If you have tried something to get it done, post your code, and you'll
    get help.
    If you are trying to get someone else to do your work, you are just
    another ... I'll reserve my comments. :)

    Anyway, here's are a couple of tips.
    1) string's c_str() returns a non-modifiable C string, so use copy()
    instead.
    2) Replace the spaces with '\0' to "create" separate strings out of the
    copied string.

    Hope this helps...

    Rgds,
    Vimal.


    --
    "If you would be a real seeker after truth, it is necessary that at
    least once in your life you doubt, as far as possible, all things."
    -- Rene Descartes
     
    Vimal Aravindashan, Oct 17, 2005
    #2
    1. Advertising

  3. most direct way ( there might be easier way),
    #include <iostream>

    #include <sstream>

    #include <string>



    using namespace std;

    int main()

    {

    string str="arg1 arg2 arg3";

    stringstream ss;

    char **s;

    int count_space = str.size() == 0 ? 0 : 1; // cover the case of empty
    string

    for(int i = 0; i < str.size(); i++)

    {

    if (str == ' ')

    count_space++;

    }

    s = new char * [count_space + 1];

    s[count_space] = NULL;


    ss << str;

    for(int i = 0; ss >> str; i++)

    {

    s = new char[str.length() + 1];

    strncpy(s,str.data(),str.length());

    s[str.length()] = '\0';

    }



    return 0;

    }

    "puzzlecracker" <> wrote in message
    news:...
    > let's say have a string: string str="arg1 arg2 arg3";
    >
    > I need to convert it to
    >
    > char **s where s={arg1, arg2,arg3, NULL};
    >
    >
    > has anyone encountered this problem and has fast solution?
    >
    > Thanks
    >
     
    Someonekicked, Oct 17, 2005
    #3
  4. puzzlecracker

    Mike Wahler Guest

    "puzzlecracker" <> wrote in message
    news:...
    > let's say have a string: string str="arg1 arg2 arg3";
    >
    > I need to convert it to
    >
    > char **s where s={arg1, arg2,arg3, NULL};
    >
    >
    > has anyone encountered this problem and has fast solution?


    #include <iostream>
    #include <string.h>

    int main()
    {
    const char *data = "arg1 arg2 arg3";
    char *a[sizeof data / sizeof *data + 1] =
    {
    strstr(data, "arg1"),
    strstr(data, "arg2"),
    strstr(data, "arg3")
    };

    char **s = a;

    size_t i = 0;

    while(s)
    {
    for(size_t j = 0; j < 4; ++j)
    std::cout.put(s[j]);

    std::cout.put('\n');
    ++i;
    }

    return 0;
    }

    This was the fastest way I could write it.

    ("Useful?", now that's a different story. :))

    -Mike
     
    Mike Wahler, Oct 17, 2005
    #4
  5. Vimal Aravindashan wrote:
    > puzzlecracker wrote:
    > > let's say have a string: string str="arg1 arg2 arg3";
    > >
    > > I need to convert it to
    > >
    > > char **s where s={arg1, arg2,arg3, NULL};
    > >
    > >
    > > has anyone encountered this problem and has fast solution?
    > >
    > > Thanks
    > >

    >
    > If you have tried something to get it done, post your code, and you'll
    > get help.
    > If you are trying to get someone else to do your work, you are just
    > another ... I'll reserve my comments. :)
    >
    > Anyway, here's are a couple of tips.
    > 1) string's c_str() returns a non-modifiable C string, so use copy()
    > instead.
    > 2) Replace the spaces with '\0' to "create" separate strings out of the
    > copied string.
    >
    > Hope this helps...
    >
    > Rgds,
    > Vimal.
    >
    >
    > --
    > "If you would be a real seeker after truth, it is necessary that at
    > least once in your life you doubt, as far as possible, all things."
    > -- Rene Descartes





    string args= "srcipt arg1 arg2 arg3..."
    .....

    int size=args.size()*2; // to make sure I have enough room
    char *argvec=new char[size];
    memset(argvec,'\0',size);
    args.copy(argvec,size);

    pid_t pid;
    if(pid=fork()<0)
    {
    cerr<<"failed in fork(), exit 1\n";
    exit(1);

    }
    else if(pid==0)
    {
    if(execv("/home/work/bin/script",&argvec)<0)
    {
    cerr<<"failed in execv, exit 1\n";
    exit(1);
    }
    }
    .....


    for some reason execv failed.. any ideas?

    ffaialed in execv, exit 1
    iled in execv, exit 1


    with
     
    puzzlecracker, Oct 17, 2005
    #5
  6. Someonekicked wrote:
    > most direct way ( there might be easier way),
    > #include <iostream>
    >
    > #include <sstream>
    >
    > #include <string>
    >
    >
    >
    > using namespace std;
    >
    > int main()
    >
    > {
    >
    > string str="arg1 arg2 arg3";
    >
    > stringstream ss;
    >
    > char **s;
    >
    > int count_space = str.size() == 0 ? 0 : 1; // cover the case of empty
    > string
    >
    > for(int i = 0; i < str.size(); i++)
    >
    > {
    >
    > if (str == ' ')
    >
    > count_space++;
    >
    > }
    >
    > s = new char * [count_space + 1];
    >
    > s[count_space] = NULL;
    >
    >
    > ss << str;
    >
    > for(int i = 0; ss >> str; i++)
    >
    > {
    >
    > s = new char[str.length() + 1];
    >
    > strncpy(s,str.data(),str.length());
    >
    > s[str.length()] = '\0';
    >
    > }
    >
    >
    >
    > return 0;
    >
    > }

    Thanks, might not work, you forgetting issue about tabs
     
    puzzlecracker, Oct 17, 2005
    #6
  7. puzzlecracker wrote:
    > Vimal Aravindashan wrote:
    >
    >>puzzlecracker wrote:
    >>
    >>>let's say have a string: string str="arg1 arg2 arg3";
    >>>
    >>>I need to convert it to
    >>>
    >>> char **s where s={arg1, arg2,arg3, NULL};
    >>>
    >>>

    >>Anyway, here's are a couple of tips.
    >>1) string's c_str() returns a non-modifiable C string, so use copy()
    >>instead.
    >>2) Replace the spaces with '\0' to "create" separate strings out of the
    >>copied string.
    >>

    >
    >
    > string args= "srcipt arg1 arg2 arg3..."
    > .....
    >
    > int size=args.size()*2; // to make sure I have enough room

    No need. args.size() will do just fine.

    > char *argvec=new char[size];
    > memset(argvec,'\0',size);

    No need for this memset either.

    > args.copy(argvec,size);
    >

    Its okay till here. After you find out how many args are there (n), this
    is what you need to do:
    NOTE: following code was not tested, so use it more like pseudocode

    char **sz;
    sz = new (char *)[n+1]; // you need a NULL at the end, right?

    sz[0] = &argvec[0]; // sz[0] will hold only the first arg (you'll see)

    c = 1; // we already have the first arg

    for(int i=0; i<args.length(); i++) {
    if(argvec==' ') {
    sz[c++] = &argvec[i+1]; // the remaining args

    argvec = '\0'; // replacing the space with '\0', makes each one
    separate.
    }
    }
    sz[c] = NULL; // the final NULL

    The remaining code has nothing to do with C++. Try a different newsgroup.


    Cheers,
    Vimal.

    > pid_t pid;
    > if(pid=fork()<0)
    > {
    > cerr<<"failed in fork(), exit 1\n";
    > exit(1);
    >
    > }
    > else if(pid==0)
    > {
    > if(execv("/home/work/bin/script",&argvec)<0)
    > {
    > cerr<<"failed in execv, exit 1\n";
    > exit(1);
    > }
    > }
    > .....
    >
    >
    > for some reason execv failed.. any ideas?
    >
    > ffaialed in execv, exit 1
    > iled in execv, exit 1
    >
    >
    > with
    >



    --
    "If you would be a real seeker after truth, it is necessary that at
    least once in your life you doubt, as far as possible, all things."
    -- Rene Descartes
     
    Vimal Aravindashan, Oct 17, 2005
    #7
  8. puzzlecracker

    Kai-Uwe Bux Guest

    puzzlecracker wrote:

    >
    > Someonekicked wrote:
    >> most direct way ( there might be easier way),
    >> #include <iostream>
    >>
    >> #include <sstream>
    >>
    >> #include <string>
    >>
    >>
    >>
    >> using namespace std;
    >>
    >> int main()
    >>
    >> {
    >>
    >> string str="arg1 arg2 arg3";
    >>
    >> stringstream ss;
    >>
    >> char **s;
    >>
    >> int count_space = str.size() == 0 ? 0 : 1; // cover the case of empty
    >> string
    >>
    >> for(int i = 0; i < str.size(); i++)
    >>
    >> {
    >>
    >> if (str == ' ')
    >>
    >> count_space++;
    >>
    >> }
    >>
    >> s = new char * [count_space + 1];
    >>
    >> s[count_space] = NULL;
    >>
    >>
    >> ss << str;
    >>
    >> for(int i = 0; ss >> str; i++)
    >>
    >> {
    >>
    >> s = new char[str.length() + 1];
    >>
    >> strncpy(s,str.data(),str.length());
    >>
    >> s[str.length()] = '\0';
    >>
    >> }
    >>
    >>
    >>
    >> return 0;
    >>
    >> }

    > Thanks, might not work, you forgetting issue about tabs


    What about:

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

    typedef char* c_string;
    typedef c_string* c_string_array;

    c_string to_c_string ( std::string const & str ) {
    // you own the result, you have to delete it.
    // use delete [] to get rid of that crap.
    c_string result = new char [ str.size() + 1 ];
    std::string::size_type i;
    for ( i = 0; i < str.size(); ++i ) {
    result = str;
    }
    result = 0;
    return( result );
    }

    c_string_array chop ( std::string const & str ) {
    // you own the result, you have to delete it.
    // use delete [] to get rid of that crap.
    // BEWARE: you have to get rid of the c_strings therein first.
    std::istringstream istr ( str );
    std::string arg;
    std::vector< c_string > dummy;
    while ( istr >> arg ) {
    dummy.push_back( to_c_string( arg ) );
    }
    c_string_array result = new c_string [ dummy.size() + 1 ];
    std::vector< c_string >::size_type i;
    for ( i = 0; i < dummy.size(); ++i ) {
    result = dummy;
    }
    result = 0;
    return ( result );
    }

    int main ( void ) {
    std::string line ( "ab cd efg" );
    c_string_array arr = chop ( line );
    for ( c_string* str_ptr = arr; *str_ptr != 0; ++str_ptr ) {
    std::cout << *str_ptr << '\n';
    delete *str_ptr;
    }
    delete arr;
    }



    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Oct 17, 2005
    #8
  9. "puzzlecracker" <> wrote in message
    news:...
    > let's say have a string: string str="arg1 arg2 arg3";
    >
    > I need to convert it to
    >
    > char **s where s={arg1, arg2,arg3, NULL};
    >
    >
    > has anyone encountered this problem and has fast solution?
    >
    > Thanks
    >


    You've not been reading recent posts, redfloyd posted a similar solution
    which
    I've shamelessly adapted....Of course, you might use strtok() to token your
    original
    string & create the array of what-have-yous.

    #include <string>
    #include <sstream>
    #include <iterator>
    #include <vector>
    int main(int argc, char* argv[])
    {

    char* ARGS[100];
    int ARGSC = 0;

    std::istringstream is(" arg1 arg2 arg3 arg4 arg5 " );
    for ( std::istream_iterator<std::string> it(is) ;
    it!=std::istream_iterator<std::string>() ; ++it, ++ARGSC)
    {
    std::string s=*it;


    ARGS[ARGSC]= strdup( s.c_str() );


    }
    return 0;

    }
     
    Dave Townsend, Oct 17, 2005
    #9
  10. Dave Townsend wrote:
    > "puzzlecracker" <> wrote in message
    > news:...
    > > let's say have a string: string str="arg1 arg2 arg3";
    > >
    > > I need to convert it to
    > >
    > > char **s where s={arg1, arg2,arg3, NULL};
    > >
    > >
    > > has anyone encountered this problem and has fast solution?
    > >
    > > Thanks
    > >

    >
    > You've not been reading recent posts, redfloyd posted a similar solution
    > which
    > I've shamelessly adapted....Of course, you might use strtok() to token your
    > original
    > string & create the array of what-have-yous.
    >
    > #include <string>
    > #include <sstream>
    > #include <iterator>
    > #include <vector>
    > int main(int argc, char* argv[])
    > {
    >
    > char* ARGS[100];
    > int ARGSC = 0;
    >
    > std::istringstream is(" arg1 arg2 arg3 arg4 arg5 " );
    > for ( std::istream_iterator<std::string> it(is) ;
    > it!=std::istream_iterator<std::string>() ; ++it, ++ARGSC)
    > {
    > std::string s=*it;
    >
    >
    > ARGS[ARGSC]= strdup( s.c_str() );
    >
    >
    > }
    > return 0;
    >
    > }



    Almost all of your solutions expose a notorious problem in c++
    community that has rather horrid and sadistic ramifications. That
    problem is memory leak. Would anyone suggest a solution where we don't
    have to deal with memory - at least directly to solve this problem?


    Ps. I said'some' because they only need one for loop to solve it.


    ps2. I hate mixing c and c++ - the task for fearless and
    ready-to-explain-your-boss-why-component-fucks-up.
     
    puzzlecracker, Oct 17, 2005
    #10
  11. "puzzlecracker" <> wrote in message
    news:...
    >
    >> puzzlecracker wrote:
    >> > let's say have a string: string str="arg1 arg2 arg3";
    >> >
    >> > I need to convert it to
    >> >
    >> > char **s where s={arg1, arg2,arg3, NULL};
    >> >
    >> >
    >> > has anyone encountered this problem and has fast solution?
    >> >
    >> > Thanks
    >> >

    >>

    >
    >
    >
    > string args= "srcipt arg1 arg2 arg3..."
    > .....
    >
    > int size=args.size()*2; // to make sure I have enough room
    > char *argvec=new char[size];
    > memset(argvec,'\0',size);
    > args.copy(argvec,size);
    >


    vector<char*> argv;
    string a ="script arg1 arg2 arg3";
    vector<char> args(a.begin(),a.end());
    args.push_back(' ');
    while(vector<char>::iterator i=args.begin(),j=args.end();i!=args.end();)
    {
    vector<char>::iterator k = find(i,j,' ');
    *k = 0;
    argv.push_back(&*i);
    i=++k;
    }
    argv.push_back(0);

    > pid_t pid;
    > if(pid=fork()<0)
    > {
    > cerr<<"failed in fork(), exit 1\n";
    > exit(1);
    >
    > }
    > else if(pid==0)
    > {
    > if(execv("/home/work/bin/script",&argvec)<0)

    if(execv("/home/work/bin/script",&argv[0])<0)
    > {
    > cerr<<"failed in execv, exit 1\n";
    > exit(1);
    > }
    > }
    > .....
    >
    >
    > for some reason execv failed.. any ideas?

    You didn't pass array of pointers to char.

    Greetings, Bane.
     
    Branimir Maksimovic, Oct 17, 2005
    #11
  12. "Branimir Maksimovic" <> wrote in message
    news:divdc6$ho4$...
    >
    > while(vector<char>::iterator i=args.begin(),j=args.end();i!=args.end();)


    should be
    for(vector<char>::iterator i=args.begin(),j=args.end();i!=args.end();)
     
    Branimir Maksimovic, Oct 17, 2005
    #12
  13. The memory has to be allocated somewhere Sunshine, you'll have
    to figure out how to release it when you're done. Alternatively, you
    can restate your problem to use strings instead of char*.


    "puzzlecracker" <> wrote in message
    news:...
    >
    > Dave Townsend wrote:
    > > "puzzlecracker" <> wrote in message
    > > news:...
    > > > let's say have a string: string str="arg1 arg2 arg3";
    > > >
    > > > I need to convert it to
    > > >
    > > > char **s where s={arg1, arg2,arg3, NULL};
    > > >
    > > >
    > > > has anyone encountered this problem and has fast solution?
    > > >
    > > > Thanks
    > > >

    > >
    > > You've not been reading recent posts, redfloyd posted a similar solution
    > > which
    > > I've shamelessly adapted....Of course, you might use strtok() to token

    your
    > > original
    > > string & create the array of what-have-yous.
    > >
    > > #include <string>
    > > #include <sstream>
    > > #include <iterator>
    > > #include <vector>
    > > int main(int argc, char* argv[])
    > > {
    > >
    > > char* ARGS[100];
    > > int ARGSC = 0;
    > >
    > > std::istringstream is(" arg1 arg2 arg3 arg4 arg5 " );
    > > for ( std::istream_iterator<std::string> it(is) ;
    > > it!=std::istream_iterator<std::string>() ; ++it, ++ARGSC)
    > > {
    > > std::string s=*it;
    > >
    > >
    > > ARGS[ARGSC]= strdup( s.c_str() );
    > >
    > >
    > > }
    > > return 0;
    > >
    > > }

    >
    >
    > Almost all of your solutions expose a notorious problem in c++
    > community that has rather horrid and sadistic ramifications. That
    > problem is memory leak. Would anyone suggest a solution where we don't
    > have to deal with memory - at least directly to solve this problem?
    >
    >
    > Ps. I said'some' because they only need one for loop to solve it.
    >
    >
    > ps2. I hate mixing c and c++ - the task for fearless and
    > ready-to-explain-your-boss-why-component-fucks-up.
    >
     
    Dave Townsend, Oct 17, 2005
    #13
    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. TN Bella
    Replies:
    1
    Views:
    2,505
    Edward
    Jun 18, 2004
  2. =?Utf-8?B?Q2hyaXM=?=

    Help Help. I really need some help with this

    =?Utf-8?B?Q2hyaXM=?=, Jan 31, 2007, in forum: ASP .Net
    Replies:
    3
    Views:
    598
    =?Utf-8?B?SmFzb24gVmVybWlsbGlvbg==?=
    Jan 31, 2007
  3. Replies:
    21
    Views:
    719
    Pete Becker
    Apr 13, 2006
  4. Angus
    Replies:
    3
    Views:
    357
  5. ElementX
    Replies:
    9
    Views:
    533
    RedGrittyBrick
    Oct 1, 2008
Loading...

Share This Page