开发者

(C++) Very Basic Questions Regarding Syntax

开发者 https://www.devze.com 2023-03-05 07:30 出处:网络
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)?

C++ novice here. I have some basic questions. In int main( int argc, char *argv[] )

  1. How is char *argv[] supposed to be read (or spoken out to humans)?
  2. Is it possible to clear/erase specific content(s), character(s) in this case, of such array? If yes, how?
  3. Can arrays be resized? If yes, how?
  4. How can I copy the entire content of argv[] to a single std::string variable?
  5. Are there other ways of determining the number of words / parameters in 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 argcat 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 );


  1. It's an array of pointers to char.

  2. Sort of - you can overwrite them.

  3. Only by copying to a new array.

  4. Write a loop and append each argv[i] to a C++ string.

  5. 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. :)


  1. Several options: array of pointer to char OR array of C-string.

  2. You can assign to particular characters to clear them, or you can shift the rest of the array forwards to "erase" characters/elements.

  3. Normal C-style arrays cannot be resized. If you need a resizable array in C++ you should use std::vector.

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

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


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


  1. 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 or int argc, char *argv[] -- which is equivalent).
  2. 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.
  3. They cannot be resized per se, but reinterpreted as a smaller array (which sort of explains the answer to the last question).
  4. 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]);.
  5. Not really. Most systems have argv NULL terminated, but that is not a guarantee.


  1. 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"

  2. 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)

  3. No, arrays cannot be resized. You will need to create a new one and copy the contents

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

  5. 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:

  1. char *argv[] can be read as 'array of pointers to char'
  2. It's possible, but involves direct manipulations with data in memory, such as copying and/or moving bytes around.
  3. No. But you may allocate new array and copy necesary data
  4. By manually copying each element into std::string object
  5. No.

As a summary: C++ is much more low-level language that you think.

0

精彩评论

暂无评论...
验证码 换一张
取 消