Reputation: 73
C++ novice here. I have some basic questions. In int main( int argc, char *argv[] )
char *argv[]
supposed to be read (or spoken out to humans)? argv[]
to a single std::string
variable?argv[]
without argc
? If yes, how? (*)I'd appreciate explanations (not code) for numbers 2-5. I'll figure out the code myself (I learn faster this way).
Thanks in advance.
(*) I know that main(char *argv[])
is illegal. What I mean is whether there's at least a way that does not involve argc
at all, like in the following expressions:
for( int i = 0; i < argc; ++i ) {
std::cout << argv[i] << std::endl;
}
and
int i = 0;
while( i < argc ) {
std::cout << argv[i] << std::endl;
++i;
}
Or
int i = 0;
do {
std::cout << argv[i] << std::endl;
++i; } while( i < argc );
Upvotes: 7
Views: 450
Reputation: 96233
Several options: array of pointer to char OR array of C-string.
You can assign to particular characters to clear them, or you can shift the rest of the array forwards to "erase" characters/elements.
Normal C-style arrays cannot be resized. If you need a resizable array in C++ you should use std::vector
.
You'll have to iterate over each of the items and append them to a string. This can be accomplished with C++ algorithms such as copy
in conjunction with an ostream_iterator
used on an ostringstream
.
No. If there was such a way, there wouldn't be any need for argc
. EDIT: Apparently for argv
only the final element of the array is a null pointer.
Upvotes: 1
Reputation: 19609
1) It is supposed to be char **argv
or char *argv[]
which is a pointer to an array of characters
more commonly known as an array of strings
2) CString is the std library to manipulate C strings (arrays of characters). You cannot resize an array without reallocating, but you can change the contents of elements by referencing it by index:
for(int i = 0; i < argc; ++i)
{
//set all the strings to have a null character in the
//first slot so all Cstring operations on this array,
//will consider it a null (empty) string
argv[i] = 0;
}
3) Technically no, however they can be deleted then reallocated:
int *array = new int[15]; //array of size 15
delete[] array;
array = new int[50]; //array of size 50
4) This is one way:
string *myString;
if(argc > 0)
{
myString = new string(argv[0]);
for(int i = 1; i < argc; ++i)
myString->append(argv[i]);
}
5) Yes, according to Cubbi:
POSIX specifies the final null pointer for argv, see for example "The application shall ensure that the last member of this array is a null pointer." at pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
Which means you can do:
char *val = NULL;
int i = 0;
do
{
val = argv[i++]; //access argv[i], store it in val, then increment i
//do something with val
} while(val != NULL); //loop until end of argv array
Upvotes: 0
Reputation: 131789
char **argv[]
Is wrong. It should be either char **argv
or char *argv[]
, not a mixture of both. And then it becomes a pointer-to-pointer to characters, or rather a pointer to c-strings, i.e., an array of c-strings. :) cdecl.org is also quite helpful at thing like this.
Then, for the access, sure. Just, well, access it. :) argv[0]
would be the first string, argv[3]
would be the 4th string. But I totally wouldn't recommend replacing stuff in an array that isn't yours or that you know the internals of.
On array resize, since you're writing C++, use std::vector
, which does all the complicated allocation stuff for you and is really safe. Generally, it depends on the array type. Dynamically allocated arrays (int* int_arr = new int[20]
) can, static arrays (int int_arr[20]
) can't.
To copy everything in argv
into a single std::string
, loop through the array and append every c-string to your std::string
. I wouldn't recommend that though, rather have a std::vector<std::string>
, i.e., an array of std::strings
, each holding one of the arguments.
std::vector<std::string> args;
for(int i=0; i < argc; ++i){
args.push_back(argv[i]);
}
On your last point, since the standard demands argv
to be terminated by a NULL
pointer, it's quite easy.
int myargc = 0;
char** argv_copy = argv;
while(++argv_copy)
++myargc;
The while(++argv_copy)
will first increment the pointer of the array, letting it point to the next element (e.g., after the first iteration it will point at c-string #2 (argv[1]
)). After that, if the pointer evaluates to false (if it is NULL
), then the loop brakes and you have your myargc
. :)
Upvotes: 1
Reputation: 238
Array in C/C++ is not an object, but just a pointer to first element of array, so you cannot simply delete or insert values.
Answering your questions:
char *argv[]
can be read as 'array of pointers to char
'std::string
objectAs a summary: C++ is much more low-level language that you think.
Upvotes: -1
Reputation: 13477
char *argv[]
can be read as: "an array of pointers to char"
char **argv
can be read as: "a pointer to a pointer to char"
Yes, you may modify the argv
array. For example, argv[0][0] = 'H'
will modify the first character of the first parameter. If by "erase/clear" you mean remove a character from the array and everything automatically shift over: there is no automatic way to do that - you will need to copy all the characters one-by-one over to the left (including the NULL termination)
No, arrays cannot be resized. You will need to create a new one and copy the contents
How do you want to represent ALL the parameter strings as 1 std::string? It would make more sense to copy it to an array of std::strings
No, there is no special indication of the last entry in the array. you need to use argc
Upvotes: 0
Reputation: 29586
int argc, char **argv
or int argc, char *argv[]
-- which is equivalent).std::list<std::string> args(&argv[1], &argv[argc]);
.NULL
terminated, but that is not a guarantee.Upvotes: 0
Reputation:
It's an array of pointers to char.
Sort of - you can overwrite them.
Only by copying to a new array.
Write a loop and append each argv[i] to a C++ string.
Most implementations terminate the array with a NULL pointer. I can't remember if this is standard or not.
Upvotes: 2