By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,775 Members | 1,399 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,775 IT Pros & Developers. It's quick & easy.

Argv

P: n/a
I'm trying to create an array of character arrays. I would use strings,
but the function I need to feed into looks like this

int execve(const char *filename, char *const argv [], char *const
envp[] ). I know this is not a C++ function, and I only ask for how to
create something that a function like this will actually accept.

I will not know the amount of character arrays (arguments) until
runtime, so I need to use new or calloc to get this done.

I've successfully parsed all the arguments into strings, and placed
them in a nice vector. (Probably an unnecessary step, but hey)

so something like

make charray;
for(int i =0; i< vector.size(); i++){

chararray[i][vector[i].c_str()];

}

return something that will pass into the above function.

Sorry if this seems weird.

Thanks for Reading.

A tired java person.

Apr 11 '06 #1
Share this Question
Share on Google+
25 Replies


P: n/a
<br****@gmail.com> schrieb im Newsbeitrag news:11**********************@g10g2000cwb.googlegr oups.com...
I'm trying to create an array of character arrays. I would use strings,
but the function I need to feed into looks like this

int execve(const char *filename, char *const argv [], char *const
envp[] ). I know this is not a C++ function, and I only ask for how to
create something that a function like this will actually accept.


The function expects two arrays of pointers to char, not "arrays of character arrays". Something like

char** argv = new char*[numberOfStrings + 1];
for (int i = 0; i < numberOfStrings; ++i)
argv[i] = somePointerToNonConstCharacter(s);
argv[numberOfStrings] = 0;

should help.

Heinz
Apr 11 '06 #2

P: n/a
i think this can work:

char **array;
array = malloc(sizeof(char *) * NUMBER_OF_STRINGS);
-------or-------
char *array[MAX_NUMBER_OF_STRINGS]; (if you don't like a malloc here :)

then:
int i;
char buffer[1024];
fgets(char *s, int size, FILE *stream);
for (i = 0; i < NUMBER_OF_STRINGS; i++)
{
fgets(buffer, 1024, stdin); // get the ith string
array[i] = malloc(sizeof(buffer)); // create new string in the
array
strcpy(array[i], buffer); // assign the string
}

execve(blah, array, blah); // pass the array

does it work?

Apr 11 '06 #3

P: n/a
Ops sorry, i forgot this was the c.l.c++, i replied in C :] Sorry!

Apr 11 '06 #4

P: n/a
??
perhalps need a argc to count the size
<br****@gmail.com>
??????:11**********************@g10g2000cwb.google groups.com...
I'm trying to create an array of character arrays. I would use strings,
but the function I need to feed into looks like this

int execve(const char *filename, char *const argv [], char *const
envp[] ). I know this is not a C++ function, and I only ask for how to
create something that a function like this will actually accept.

I will not know the amount of character arrays (arguments) until
runtime, so I need to use new or calloc to get this done.

I've successfully parsed all the arguments into strings, and placed
them in a nice vector. (Probably an unnecessary step, but hey)

so something like

make charray;
for(int i =0; i< vector.size(); i++){

chararray[i][vector[i].c_str()];

}

return something that will pass into the above function.

Sorry if this seems weird.

Thanks for Reading.

A tired java person.

Apr 11 '06 #5

P: n/a
>
I've successfully parsed all the arguments into strings, and placed
them in a nice vector. (Probably an unnecessary step, but hey)

char** vector_to_valist (const std::vector<std::string>& vect)
{
std::auto_ptr<char*> valist (new char* [vect.size()]);
std::transform (vect.begin(), vect.end(),
const_cast<const char**> (valist.get()),
std::mem_fun_ref (&std::string::c_str));
return valist.release();
}

theres some const breakage going on here, but the exec family doesn't
mod the strings anyway.
Apr 11 '06 #6

P: n/a
In article <11**********************@g10g2000cwb.googlegroups .com>,
br****@gmail.com wrote:
I'm trying to create an array of character arrays. I would use strings,
but the function I need to feed into looks like this

int execve(const char *filename, char *const argv [], char *const
envp[] ). I know this is not a C++ function, and I only ask for how to
create something that a function like this will actually accept.
From unistd.h right?
I will not know the amount of character arrays (arguments) until
runtime, so I need to use new or calloc to get this done.
No, don't use calloc. Don't ever use calloc in a C++ program.
I've successfully parsed all the arguments into strings, and placed
them in a nice vector. (Probably an unnecessary step, but hey)

so something like

make charray;
for(int i =0; i< vector.size(); i++){

chararray[i][vector[i].c_str()];
The problem with that is that both argv and envp must contain modifiable
strings (char* not const char*.)
return something that will pass into the above function.

Sorry if this seems weird.

struct extract_buffer : unary_function< char*, vector<char> > {
char* operator()( vector<char>& vec ) const {
return &vec[0];
}
};

typedef vector< vector< char > > RaggedArray;

int execve( const char* filename, RaggedArray& argv,
RaggedArray& envp ) {
vector<char*> argv_guts;
transform( argv.begin(), argv.end(), back_inserter( argv_guts ),
extract_buffer() );
vector<char*> envp_guts;
transform( envp.begin(), envp.end(), back_inserter( envp_guts ),
extract_buffer() );
return execve( filename, &argv_guts[0], &envp_guts[0] );
}
--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Apr 11 '06 #7

P: n/a
pillbug wrote:

I've successfully parsed all the arguments into strings, and placed
them in a nice vector. (Probably an unnecessary step, but hey)
char** vector_to_valist (const std::vector<std::string>& vect)
{
std::auto_ptr<char*> valist (new char* [vect.size()]);


auto_ptr should not control an array returned by new[], because the result
of calling delete (without []) on it is undefined.
std::transform (vect.begin(), vect.end(),
const_cast<const char**> (valist.get()),
std::mem_fun_ref (&std::string::c_str));
return valist.release();
}

theres some const breakage going on here, but the exec family doesn't
mod the strings anyway.


I don't trust that const_cast. Why not use vector<char*> valist, then get
its first element's address with &valist[0]?

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 11 '06 #8

P: n/a
pillbug wrote:
char** vector_to_valist (const std::vector<std::string>& vect)
{ .... return valist.release();
}


I forgot to notice; that return value is just wrong. If you need a
vector<char*>, then return one. Or better vector<string>. Return it by
copy.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 11 '06 #9

P: n/a

Daniel T. wrote:
I will not know the amount of character arrays (arguments) until
runtime, so I need to use new or calloc to get this done.


No, don't use calloc. Don't ever use calloc in a C++ program.


why? :-)
std::calloc() is quite useful in some cases

Apr 11 '06 #10

P: n/a
Diego Martins wrote:
why? :-)
std::calloc() is quite useful in some cases


Name a situation where you can't use new char[], or a similar correctly
typed alternative.

(And don't get us started about custom allocators in containers, etc.)

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 11 '06 #11

P: n/a
pillbug wrote:

I've successfully parsed all the arguments into strings, and placed
them in a nice vector. (Probably an unnecessary step, but hey)

char** vector_to_valist (const std::vector<std::string>& vect)
{
std::auto_ptr<char*> valist (new char* [vect.size()]);
std::transform (vect.begin(), vect.end(),
const_cast<const char**> (valist.get()),
std::mem_fun_ref (&std::string::c_str));
return valist.release();
}

theres some const breakage going on here, but the exec family doesn't
mod the strings anyway.


And other evilness. std::auto_ptr takes a pointer to object, not an
array of object. In the event of an exception being thrown by
std::transform (or any method called by it), you will have undefined
behaviour as std::auto_ptr attempts to delete a pointer that was created
by new[].
Apr 11 '06 #12

P: n/a
Thanks for the replies, but maybe i phrased the question in such a way
that the answers seem more complicated to me than I think they should
be.

I need to turn one long string of the format:

"UNIXCOMMAND ARG1 ARG2 ARG3"

Into a suitable data structure. I then need to pass the pointer to this
data structure out of its class so that I can run this function.

//COMMANDLINE CLASS

datamembers:
char ** argv;

CommandLine::CommandLine(istream & in)
{
create argv

}

char**CommandLine::getCommandLine(){

return pointer to argv
}
int execve(const char *filename, char *const argv [], char *const
envp[] )

Maybe this makes it easier to understand what I'm asking.

Apr 11 '06 #13

P: n/a
Thanks for the replies, but maybe i phrased the question in such a way
that the answers seem more complicated to me than I think they should
be.

I need to turn one long string of the format:

"UNIXCOMMAND ARG1 ARG2 ARG3"

Into a suitable data structure. I then need to pass the pointer to this
data structure out of its class so that I can run this function.
int execve(const char *filename, char *const argv [], char *const
envp[] )


//COMMANDLINE CLASS

datamembers:
char ** argv;

CommandLine::CommandLine(istream & in)
{
create argv

}

char**CommandLine::getCommandLine(){

return pointer to argv

}
Maybe this makes it easier to understand what I'm asking.

Apr 11 '06 #14

P: n/a
In article <11**********************@e56g2000cwe.googlegroups .com>,
"Diego Martins" <jo********@gmail.com> wrote:
Daniel T. wrote:
I will not know the amount of character arrays (arguments) until
runtime, so I need to use new or calloc to get this done.
No, don't use calloc. Don't ever use calloc in a C++ program.


why? :-)


Because any situation where you would be using malloc, you shouldn't be
using it, and calloc can only be used on memory returned by malloc.

std::calloc() is quite useful in some cases


Is it? What cases might those be? Let me make that a more general
question, is there any C++ program where a vector cannot be used in
place of a malloc/calloc combination, and in which the use of the vector
isn't a better choice?
--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Apr 11 '06 #15

P: n/a
Daniel T. wrote:
why? :-)


Because any situation where you would be using malloc, you shouldn't be
using it, and calloc can only be used on memory returned by malloc.


I thought calloc() was figuratively an overload of malloc(), just with
different arguments. Are you answering for realloc()? (It's the same
answer, anyway...)

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 11 '06 #16

P: n/a
Phlip wrote:
Daniel T. wrote:
why? :-)


Because any situation where you would be using malloc, you
shouldn't be using it, and calloc can only be used on memory
returned by malloc.


I thought calloc() was figuratively an overload of malloc(), just with
different arguments. Are you answering for realloc()? (It's the same
answer, anyway...)


Well, calloc() sets the individual bytes to all-bits-zero. This is
sometimes useful in C, although not as often as people seem to think.

Brian
Apr 11 '06 #17

P: n/a
In article <zF*****************@newssvr33.news.prodigy.com> ,
Phlip <ph*******@gmail.com> wrote:
Daniel T. wrote:
why? :-)


Because any situation where you would be using malloc, you shouldn't be
using it, and calloc can only be used on memory returned by malloc.


I thought calloc() was figuratively an overload of malloc(), just with
different arguments. Are you answering for realloc()? (It's the same
answer, anyway...)


Yes, a minor confusion on my part. Guess that shows how often I use
them. :-)
--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Apr 11 '06 #18

P: n/a
Default User wrote:
Well, calloc() sets the individual bytes to all-bits-zero. This is
sometimes useful in C, although not as often as people seem to think.


Righteous. NULL, in C, sometimes ain't zero, so a struct containing pointers
won't get correctly initialized. Ouch.

Daniel T. wrote:
Are you answering for realloc()?


Yes, a minor confusion on my part. Guess that shows how often I use
them. :-)


Yay! I won a technical debate!! Oh, I feel giddy now!!!

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 11 '06 #19

P: n/a
Phlip wrote:
Default User wrote:
Well, calloc() sets the individual bytes to all-bits-zero. This is
sometimes useful in C, although not as often as people seem to
think.


Righteous. NULL, in C, sometimes ain't zero, so a struct containing
pointers won't get correctly initialized. Ouch.


0 is a null pointer constant in either language. In C, it can also be
something like (void *)0. Neither language requires the actual pointer
to be all-bits-zero, just that the assignments and comparisons all work.


Brian
Apr 11 '06 #20

P: n/a
Default User objected to:
Righteous. NULL, in C, sometimes ain't zero


This is a metaphor for "sometimes NULL is not 'all bits off'". So you can't
memset( , 0, ) a pointer in either language and portably turn off all bits.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 11 '06 #21

P: n/a
Phlip wrote:
Default User objected to:
Righteous. NULL, in C, sometimes ain't zero


This is a metaphor for "sometimes NULL is not 'all bits off'". So you
can't memset( , 0, ) a pointer in either language and portably turn
off all bits.


NULL is a macro defined as a null pointer constant. In C, (void *)0 or
equivalent is a null pointer constant, but obviously couldn't be so in
C++. NULL can be all-bits-zero and still not have a null pointer be so.

void *p;

p = 0; // this guaranatees a null pointer

memset (&p, sizeof p, 0); // does not

A null pointer constant is converted to a null pointer when used in an
assignment, initialization, or comparison.

What I was objecting to was this, "NULL, in C, sometimes ain't zero, so
a struct containing pointers won't get correctly initialized."

It has nothing to do with C versus C++, the same is true of either
language. It also has nothing to do with the value of NULL, which must
be a null pointer constant.

Brian
Apr 11 '06 #22

P: n/a
Pillbug's solution worked well

std::auto_ptr<char*> valist (new char* [vect.size()+1]); --> you
must add one here to insert a null char pointer
std::transform (vect.begin(), vect.end(),
const_cast<const char**> (valist.get()),
std::mem_fun_ref (&std::string::c_str));
argv=valist.release();
argv[vect.size()]=(char *)0; -->> add the null pointer per
execve, I think it was size() and not size()+1
Thanks!

Apr 12 '06 #23

P: n/a
broeks wrote:
std::auto_ptr<char*> valist (new char* [vect.size()+1]); --> you


Don't use auto_ptr to store a pointer from new[]. It causes undefined
behavior when the auto_ptr destructor calls delete instead of delete[].

It will probably appear to work correctly. That's one possible outcome of
undefined behavior. Don't rely on it.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 12 '06 #24

P: n/a
In article <11**********************@v46g2000cwv.googlegroups .com>,
br****@gmail.com wrote:
Thanks for the replies, but maybe i phrased the question in such a way
that the answers seem more complicated to me than I think they should
be.

I need to turn one long string of the format:

"UNIXCOMMAND ARG1 ARG2 ARG3"

Into a suitable data structure. I then need to pass the pointer to this
data structure out of its class so that I can run this function.
int execve(const char *filename, char *const argv [], char *const
envp[] )


//COMMANDLINE CLASS

datamembers:
char ** argv;

CommandLine::CommandLine(istream & in)
{
create argv

}

char**CommandLine::getCommandLine(){

return pointer to argv

}
Maybe this makes it easier to understand what I'm asking.


In that case, and assuming that execve really doesn't change the values
inside the char*s:

void execve( const char* filename, istream& is ) {
vector<char*> argv;
vector<string> data;
copy( istream_iterator<string>( is ), istream_iterator<string>(),
back_inserter( data ) );
for ( vector<string>::iterator it = data.begin();
it != data.end(); ++it )
argv.push_back( const_cast<char*>( it->c_str() ) );
argv.push_back( 0 );
execve( filename, &argv[0], 0 );
}

--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Apr 12 '06 #25

P: n/a
>
std::auto_ptr<char*> valist (new char* [vect.size()+1]); --> you

Don't use auto_ptr to store a pointer from new[]. It causes undefined
behavior when the auto_ptr destructor calls delete instead of delete[].


yeah don't use the auto_ptr, that was a good catch which i corrected
in my own code hehe. thanks :) but the rest of the fuction works
no problemo.
Apr 13 '06 #26

This discussion thread is closed

Replies have been disabled for this discussion.