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

a question about char**

P: n/a
I just wonder how to pass arguments to this function with a char**

void oldmain(int argv, char**argc)
{
........
}

void main(void)
{
int argv;
char ** argc;

string cmd[ ] = {"hello", "again", "again"};

// ????????? how to populate cmd[] into **argc

oldmain(argv, argc);
}

how to populate cmd[] into argc, the number of string in cmd[] is not
fixed.
thanks

Dec 15 '06 #1
Share this Question
Share on Google+
9 Replies


P: n/a
happyvalley napsal:
I just wonder how to pass arguments to this function with a char**

void oldmain(int argv, char**argc)
I would name it
void oldmain(int argc, char** argv)

argc means argument count
argv menas argument values
{
........
}

void main(void)
{
int argv;
char ** argc;

string cmd[ ] = {"hello", "again", "again"};

// ????????? how to populate cmd[] into **argc

oldmain(argv, argc);
}

how to populate cmd[] into argc, the number of string in cmd[] is not
fixed.
thanks
oldmain(sizeof(cmd) / sizeof(cmd[0]), cmd);

Dec 15 '06 #2

P: n/a

Ondra Holub wrote:
happyvalley napsal:
I just wonder how to pass arguments to this function with a char**

void oldmain(int argv, char**argc)

I would name it
void oldmain(int argc, char** argv)

argc means argument count
argv menas argument values
{
........
}

void main(void)
{
int argv;
char ** argc;

string cmd[ ] = {"hello", "again", "again"};

// ????????? how to populate cmd[] into **argc

oldmain(argv, argc);
}

how to populate cmd[] into argc, the number of string in cmd[] is not
fixed.
thanks

oldmain(sizeof(cmd) / sizeof(cmd[0]), cmd);
cmd is a string[], oldmain() cannot cast it to char**

Dec 15 '06 #3

P: n/a

happyvalley wrote:
I just wonder how to pass arguments to this function with a char**

void oldmain(int argv, char**argc)
Those names are the opposite of the traditional names, and are
extremely likely to lead to confusion.
{
........
}

void main(void)
main() always, always returns int. In C++, it has never been allowed to
return anything else. Your implementation may allow you to get away
with this, but the moment you write such a thing, it's no longer C++,
and not topical to this newsgroup. You don't even need to write a
return statement, since a zero-return is implicit otherwise: just
change the first "void" to an "int".
{
int argv;
char ** argc;
See above about confusing names...
>
string cmd[ ] = {"hello", "again", "again"};

// ????????? how to populate cmd[] into **argc

oldmain(argv, argc);
}

how to populate cmd[] into argc, the number of string in cmd[] is not
fixed.
thanks
I'm not sure you've given us enough information to answer your
question. First off: why must it be an array of std::string's (which is
what I'm assuming you're using, though you neither #included the
appropriate headers nor imported the appropriate name std)? Is it
something user-specified, or what?

If I had full control over your main() above, I'd have simply written
it with:

int argc;
char *argv[] = {"hello","again","again"};

And passed that argv to oldmain(). (Note that the above involves some
deprecated conversions from const char* to char*, and may not be
portable to future versions of the C++ language.)

What did you mean by "the number of [strings] in cmd[] is not fixed"?
The number of elements in any array is fixed. Perhaps your real code
doesn't use an array?

In either case, if you're really stuck with the input being C++
std::string's, then you cannot avoid copying them into a new array of
C-strings (the space for which you will need to allocate yourself). If
you're not really using an array for the srings (a std::vector,
perhaps), then you will proably need to allocate the space for the
array of (char*)s as well.

-Micah

Dec 15 '06 #4

P: n/a

Micah Cowan wrote:
happyvalley wrote:
I just wonder how to pass arguments to this function with a char**

void oldmain(int argv, char**argc)

Those names are the opposite of the traditional names, and are
extremely likely to lead to confusion.
{
........
}

void main(void)

main() always, always returns int. In C++, it has never been allowed to
return anything else. Your implementation may allow you to get away
with this, but the moment you write such a thing, it's no longer C++,
and not topical to this newsgroup. You don't even need to write a
return statement, since a zero-return is implicit otherwise: just
change the first "void" to an "int".
{
int argv;
char ** argc;

See above about confusing names...

string cmd[ ] = {"hello", "again", "again"};

// ????????? how to populate cmd[] into **argc

oldmain(argv, argc);
}

how to populate cmd[] into argc, the number of string in cmd[] is not
fixed.
thanks

I'm not sure you've given us enough information to answer your
question. First off: why must it be an array of std::string's (which is
what I'm assuming you're using, though you neither #included the
appropriate headers nor imported the appropriate name std)? Is it
something user-specified, or what?

If I had full control over your main() above, I'd have simply written
it with:

int argc;
char *argv[] = {"hello","again","again"};

And passed that argv to oldmain(). (Note that the above involves some
deprecated conversions from const char* to char*, and may not be
portable to future versions of the C++ language.)

What did you mean by "the number of [strings] in cmd[] is not fixed"?
The number of elements in any array is fixed. Perhaps your real code
doesn't use an array?

In either case, if you're really stuck with the input being C++
std::string's, then you cannot avoid copying them into a new array of
C-strings (the space for which you will need to allocate yourself). If
you're not really using an array for the srings (a std::vector,
perhaps), then you will proably need to allocate the space for the
array of (char*)s as well.

-Micah
Hi, Micah

thanks a lot for your correction and your time.
don't worry about the variable name, my typo. anyway thanks for
reminder
basically, I have a program running accepting arguments from char**
argv. the number of arguments is not fixed.

now I wrap this within a server, now my server receive a query command
string from the client. the string is parsered into several tokens and
I want to populate them into char** cmd
and then call the old main function oldmain(int argc, char**argv).
in this way, I can easily debug the code in standalone mode, and wrap
it within the server by just changing the main function name.

#include .....
int oldmain(int argc, char**argv)
{
...... // do something
return 0;
}

int main(void)
{
//create a socket
// connect to a client
// receive a string from client
string acmd = myServer.readFromClient()

// now I parse the string into char**argv
stringstream os(astr);
vector<stringargc;
argv.push_back("nameofthisprograme")

string temp;
while (os>>temp)
argv.push_back(temp);

// now I have the arguments saved in a string vector, just wonder
how to populate them
//into char**.
char **tempargv;
// ?????????

oldmain( argv.length(), tempargv);

return 0;
}

thanks, hope this 'v made the question clear,

Dec 15 '06 #5

P: n/a

happyvalley napsal:
Ondra Holub wrote:
happyvalley napsal:
I just wonder how to pass arguments to this function with a char**
>
void oldmain(int argv, char**argc)
I would name it
void oldmain(int argc, char** argv)

argc means argument count
argv menas argument values
{
........
}
>
void main(void)
{
int argv;
char ** argc;
>
string cmd[ ] = {"hello", "again", "again"};
>
// ????????? how to populate cmd[] into **argc
>
oldmain(argv, argc);
}
>
how to populate cmd[] into argc, the number of string in cmd[] is not
fixed.
thanks
oldmain(sizeof(cmd) / sizeof(cmd[0]), cmd);

cmd is a string[], oldmain() cannot cast it to char**
Ooops... I didn't see that, sorry. There is no simple command to
convert array of strings to array of char*. You have to either create
new array of char* from array of std::string or overload function
oldmain to accept array of string.

Dec 15 '06 #6

P: n/a
happyvalley wrote:
Hi, Micah

thanks a lot for your correction and your time.
don't worry about the variable name, my typo. anyway thanks for
reminder
basically, I have a program running accepting arguments from char**
argv. the number of arguments is not fixed.

now I wrap this within a server, now my server receive a query command
string from the client. the string is parsered into several tokens and
I want to populate them into char** cmd
and then call the old main function oldmain(int argc, char**argv).
in this way, I can easily debug the code in standalone mode, and wrap
it within the server by just changing the main function name.

#include .....
int oldmain(int argc, char**argv)
{
...... // do something
return 0;
}

int main(void)
{
//create a socket
// connect to a client
// receive a string from client
string acmd = myServer.readFromClient()

// now I parse the string into char**argv
stringstream os(astr);
vector<stringargc;
argv.push_back("nameofthisprograme")

string temp;
while (os>>temp)
argv.push_back(temp);

// now I have the arguments saved in a string vector, just wonder
how to populate them
//into char**.
char **tempargv;
// ?????????

oldmain( argv.length(), tempargv);

return 0;
}

thanks, hope this 'v made the question clear,
If it were me, I probably wouldn't bother with the vector of C++
strings in the first place. I'd probably do a vector of
pointers-to-char, and then pass the address of the first element as
argv (given that that is now explicitly well-defined in C++03).

If you'd prefer to convert to C++ strings and then into C strings,
though, you'll first need to dynamically allocate an array of C
strings:

char **tempargv = new (char *[ argv.size()+ 1 ]);
// new array of {arv.size()+1} pointers to char
tempargv[argv.size()] = 0;
// that's what the + 1 was for: argv is
// required to end with a null pointer.

And then allocate space for new C strings to go in there, perhaps via:

for (vector<string>::size_type s = 0; s != argv.size(); ++s) {
tempargv[s] = new char[argv[s].size() + 1];
// + 1 for the terminating null byte
memcpy(tempargv[s], argv[s].c_str(), argv[s].size() + 1);
// or: copy(argv[s].begin(), argv[s].end(), tempargv[s]);
}

The code above assumes some potential additions to your #include-list,
and possibly to your using declarations as well.

Don't just copy-and-paste the solution I've given you: if anything
about the above allocation-and-copy loop is unclear to you, please ask
about it. Failing to learn from this exercise would be the worst
blunder you could make. :)

-Micah

Dec 15 '06 #7

P: n/a

Micah Cowan wrote:
happyvalley wrote:
Hi, Micah

thanks a lot for your correction and your time.
don't worry about the variable name, my typo. anyway thanks for
reminder
basically, I have a program running accepting arguments from char**
argv. the number of arguments is not fixed.

now I wrap this within a server, now my server receive a query command
string from the client. the string is parsered into several tokens and
I want to populate them into char** cmd
and then call the old main function oldmain(int argc, char**argv).
in this way, I can easily debug the code in standalone mode, and wrap
it within the server by just changing the main function name.

#include .....
int oldmain(int argc, char**argv)
{
...... // do something
return 0;
}

int main(void)
{
//create a socket
// connect to a client
// receive a string from client
string acmd = myServer.readFromClient()

// now I parse the string into char**argv
stringstream os(astr);
vector<stringargc;
argv.push_back("nameofthisprograme")

string temp;
while (os>>temp)
argv.push_back(temp);

// now I have the arguments saved in a string vector, just wonder
how to populate them
//into char**.
char **tempargv;
// ?????????

oldmain( argv.length(), tempargv);

return 0;
}

thanks, hope this 'v made the question clear,

If it were me, I probably wouldn't bother with the vector of C++
strings in the first place. I'd probably do a vector of
pointers-to-char, and then pass the address of the first element as
argv (given that that is now explicitly well-defined in C++03).

If you'd prefer to convert to C++ strings and then into C strings,
though, you'll first need to dynamically allocate an array of C
strings:
Sorry, i disagree with the above statement, a std::vector< std::string
is the perfect candidate for the job at hand. Also, std::string's c_str() member function returns a const pointer to a C-type terminated string in the case that's required.
The OP can simply declare oldmain(...) with a reference to that vector:

#include <iostream>
#include <ostream>
#include <vector>
#include <iterator>

int oldmain(std::vector< std::string >& r_v)
{
std::copy( r_v.begin(),
r_v.end(),
std::ostream_iterator< std::string >(std::cout, "\n") );
return 0;
}

int main(int argc, char* argv[])
{
std::vector< std::string vs;
for(int i = 0; i < argc; ++i)
{
vs.push_back(argv[i]);
}
int result = oldmain( vs );

// in the case of cmd:
std::string cmd[ ] = {"hello", "again", "another"};
std::vector< std::string vcmd(cmd, cmd + 3); // one past the end
oldmain( vcmd );

return result;
}

Dec 15 '06 #8

P: n/a
Salt_Peter wrote:
Micah Cowan wrote:
happyvalley wrote:
#include .....
int oldmain(int argc, char**argv)
{
...... // do something
return 0;
}
>
int main(void)
{
//create a socket
// connect to a client
// receive a string from client
string acmd = myServer.readFromClient()
>
// now I parse the string into char**argv
stringstream os(astr);
vector<stringargc;
argv.push_back("nameofthisprograme")
>
string temp;
while (os>>temp)
argv.push_back(temp);
>
// now I have the arguments saved in a string vector, just wonder
how to populate them
//into char**.
char **tempargv;
// ?????????
>
oldmain( argv.length(), tempargv);
>
return 0;
}
>
thanks, hope this 'v made the question clear,
If it were me, I probably wouldn't bother with the vector of C++
strings in the first place. I'd probably do a vector of
pointers-to-char, and then pass the address of the first element as
argv (given that that is now explicitly well-defined in C++03).

If you'd prefer to convert to C++ strings and then into C strings,
though, you'll first need to dynamically allocate an array of C
strings:

Sorry, i disagree with the above statement, a std::vector< std::string
is the perfect candidate for the job at hand. Also, std::string's c_str() member function returns a const pointer to a C-type terminated string in the case that's required.
(The immediately above line ends up looking a bit strange when
quoted... oh, well.)

Actually, you don't disagree with the above statement, which I
carefully qualified with an assumption ("if you'd prefer..."), whose
condition you have discarded. ^_^
The OP can simply declare oldmain(...) with a reference to that vector:
Of course he should, and it makes for a far simpler/more elegant
solution. I was assuming that, for some reason or other, the OP
couldn't do this practically, as it seemed the obvious first choice.
But I may have been assuming too much; I should have mentioned this
explicitly. And meant to, actually.
#include <iostream>
#include <ostream>
#include <vector>
#include <iterator>

int oldmain(std::vector< std::string >& r_v)
{
std::copy( r_v.begin(),
r_v.end(),
std::ostream_iterator< std::string >(std::cout, "\n") );
return 0;
}

int main(int argc, char* argv[])
{
std::vector< std::string vs;
for(int i = 0; i < argc; ++i)
{
vs.push_back(argv[i]);
}
int result = oldmain( vs );

// in the case of cmd:
std::string cmd[ ] = {"hello", "again", "another"};
std::vector< std::string vcmd(cmd, cmd + 3); // one past the end
My one complaint with your otherwise excellent example is the magic
number above. The moment the number of elements in cmd[] is changed,
the above line is broken.

(sizeof cmd)/(sizeof cmd[0]) has the advantage of being a good deal
more flexible, and the disadvantage of being a good deal more
complicated. This is one of the few cases in C++ where I still tend to
use a preprocessing macro, such as NUM_ELEM(ary).
oldmain( vcmd );

return result;
}
Yes, thanks for implementing the better behavior of returning
oldmain()'s result, instead of simply discarding it as in the OP's
original example.

Dec 16 '06 #9

P: n/a
happyvalley wrote:
>
thanks a lot for your correction and your time. don't worry about
the variable name, my typo. anyway thanks for reminder basically, I
have a program running accepting arguments from char** argv. the
number of arguments is not fixed.

now I wrap this within a server, now my server receive a query
command string from the client. the string is parsered into several
tokens and I want to populate them into char** cmd and then call the
old main function oldmain(int argc, char**argv). in this way, I
can easily debug the code in standalone mode, and wrap it within the
server by just changing the main function name.
// what should this be?
http://www.research.att.com/~bs/bs_faq2.html#void-main
int oldmain( int argc, char* argv[] )
{
// do something
return 0;
}

template < typename T >
T* getPtr( vector<T>& vec )
{
return &vec[0];
}

int main()
{
vector<vector<char args( 1 );
const char* program = "nameofthisprograme";
copy( program, program + strlen( program ) + 1,
back_inserter( args.back() ) );
{
//create a socket
// connect to a client
// receive a string from client
string acmd = myServer.readFromClient()

stringstream os( acmd );
string temp;
while ( os >temp ) {
args.push_back( vector< char >() );
copy( temp.begin(), temp.end(), back_inserter( args.back() )
);
args.back().push_back( 0 );
}
} // force acmd, os, and temp to release their memory

vector< char* argv;
transform( args.begin(), args.end(), back_inserter( argv ),
&getPtr<char);
int result = oldmain( argv.size(), &argv[0] );
// handle result
return 0;
}

The nice thing about this solution is that there is no need to delete
anything, the vector class takes care of that for you.

Dec 16 '06 #10

This discussion thread is closed

Replies have been disabled for this discussion.