(C++) Very Basic Questions Regarding Syntax
C++ novice here. I have some basic questions. In int main( int argc, char *argv[] )
- How is
char *argv[]
supposed to be read (or spoken out to humans)? - Is it possible to clear/erase specific content(s), character(s) in this case, of such array? If yes, how?
- Can arrays be resized? If yes, how?
- How can I copy the entire content of
argv[]
to a singlestd::string
variable? - Are there other ways of determining the number of words / parameters in
argv[]
withoutargc
? 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 &l开发者_StackOverflow中文版t; argc ) {
std::cout << argv[i] << std::endl;
++i;
}
Or
int i = 0;
do {
std::cout << argv[i] << std::endl;
++i; } while( i < argc );
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.
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
. :)
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 anostream_iterator
used on anostringstream
.No. If there was such a way, there wouldn't be any need for
argc
. EDIT: Apparently forargv
only the final element of the array is a null pointer.
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
- It is spoken as "array of pointers to pointers to character" (note that this is not the signature of the main function, which is either
int argc, char **argv
orint argc, char *argv[]
-- which is equivalent). - The argv array is modifiable (lack of const). It is illegal to write beyond the end of one of the strings though or extend the array; if you need to extend a string, create a copy of it and store a pointer in the array; if you need to extend the array, create a copy of the array.
- They cannot be resized per se, but reinterpreted as a smaller array (which sort of explains the answer to the last question).
- You will be losing information this way -- argv is an array of arrays, because the individual arguments have already been separated for you. You could create a list of strings using
std::list<std::string> args(&argv[1], &argv[argc]);
. - Not really. Most systems have argv
NULL
terminated, but that is not a guarantee.
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
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 tochar
'- It's possible, but involves direct manipulations with data in memory, such as copying and/or moving bytes around.
- No. But you may allocate new array and copy necesary data
- By manually copying each element into
std::string
object - No.
As a summary: C++ is much more low-level language that you think.
精彩评论