473,416 Members | 1,660 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,416 software developers and data experts.

a question about char**

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
9 2233
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

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

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

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

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
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

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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: LaBird | last post by:
Dear all, I'd like to ask for the following C code segment: #include <stdio.h> int main() { char *a = "abc"; /* Line 1 */ printf("%s", a); /* Line 2 */ a = '1'; /* Line...
13
by: chellappa | last post by:
hi , please explain me , char pointer , char Array, char ,string... i have some many confussion about this... please clarify to me.. i need some example about this program by chellappa.ns
13
by: Betaver | last post by:
What char represent "a new line"?13 or 10, or both? I got a lot of problem when read a char. Eg. ======== 1 2 a b ======== If I write: int n1,n2; char c1,c2;
9
by: anongroupaccount | last post by:
I know that char will always be one byte, and that the size of a byte might not be 8-bits on some computers. Does that mean that an unsigned char might be able to hold numbers larger than 255 on...
6
by: comp.lang.c++ | last post by:
this is a sample example about this question #include<stdio.h> void chg(char* t) { char *s=t; char p=*t; while(*t++=*++s); *--t=p; } int main()
6
Nepomuk
by: Nepomuk | last post by:
Hi there! I was trying something with strings in C++ and ran into a problem. I wanted to write a program to do the following task: Read two "string" inputs and combine them into a third "string"....
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.