need help with string

P

puzzlecracker

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
 
V

Vimal Aravindashan

puzzlecracker said:
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.
 
S

Someonekicked

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;

}
 
M

Mike Wahler

puzzlecracker said:
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
 
P

puzzlecracker

Vimal said:
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.




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
 
P

puzzlecracker

Someonekicked said:
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
 
V

Vimal Aravindashan

puzzlecracker said:
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.
 
K

Kai-Uwe Bux

puzzlecracker said:
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
 
D

Dave Townsend

puzzlecracker said:
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;

}
 
P

puzzlecracker

Dave said:
puzzlecracker said:
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.
 
B

Branimir Maksimovic

puzzlecracker said:
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.
 
B

Branimir Maksimovic

Branimir Maksimovic said:
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();)
 
D

Dave Townsend

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 said:
Dave said:
puzzlecracker said:
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top