简体   繁体   English

(C ++)关于语法的非常基本的问题

[英](C++) Very Basic Questions Regarding Syntax

C++ novice here. 这里是C ++新手。 I have some basic questions. 我有一些基本问题。 In int main( int argc, char *argv[] ) int main( int argc, char *argv[] )

  1. How is char *argv[] supposed to be read (or spoken out to humans)? 如何将char *argv[]读取(或向人类说出)?
  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? 如何将argv[]的整个内容复制到单个std::string变量中?
  5. Are there other ways of determining the number of words / parameters in argv[] without argc ? 是否有其他方法可以确定没有argc argv[]单词 / 参数数量? If yes, how? 如果有,怎么样? (*) (*)

I'd appreciate explanations (not code) for numbers 2-5. 我很感激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. (*)我知道main(char *argv[])是非法的。 What I mean is whether there's at least a way that does not involve argc at all, like in the following expressions: 我的意思是,是否至少有一种方式根本不涉及argc ,如下面的表达式:

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 );
  1. It's an array of pointers to char. 它是一个指向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. 编写一个循环并将每个argv [i]附加到C ++字符串。

  5. Most implementations terminate the array with a NULL pointer. 大多数实现使用NULL指针终止数组。 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. 它应该是char **argvchar *argv[] ,而不是两者的混合。 And then it becomes a pointer-to-pointer to characters, or rather a pointer to c-strings, ie, an array of c-strings. 然后它成为指向字符的指针,或者更确切地说是指向c字符串的指针,即c字符串数组。 :) cdecl.org is also quite helpful at thing like this. :) cdecl.org在这样的事情上也很有帮助。
Then, for the access, sure. 然后,对于访问,当然。 Just, well, access it. 只是,好吧,访问它。 :) argv[0] would be the first string, argv[3] would be the 4th string. :) argv[0]将是第一个字符串, argv[3]将是第4个字符串。 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. 在数组调整大小,因为你正在编写C ++,使用std::vector ,它可以为你完成所有复杂的分配工作并且非常安全。 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. 动态分配的数组( int* int_arr = new int[20] )可以,静态数组( int int_arr[20] )不能。
To copy everything in argv into a single std::string , loop through the array and append every c-string to your std::string . 要将argv所有内容复制到单个std::string ,请遍历数组并将每个c字符串附加到std::string I wouldn't recommend that though, rather have a std::vector<std::string> , ie, an array of std::strings , each holding one of the arguments. 我不建议这样做,而是有一个std::vector<std::string> ,即一个std::strings数组,每个都持有一个参数。

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. 在你的最后一点,由于标准要求argvNULL指针终止,所以很容易。

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 (eg, after the first iteration it will point at c-string #2 ( argv[1] )). while(++argv_copy)将首先递增数组的指针,让它指向下一个元素(例如,在第一次迭代之后它将指向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 . 之后,如果指针的计算结果为false(如果它为NULL ),则循环制动并且你有你的myargc :) :)

  1. Several options: array of pointer to char OR array of C-string. 几个选项:指向char的指针数组或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. 普通的C风格数组无法调整大小。 If you need a resizable array in C++ you should use std::vector . 如果你需要在C ++中使用可调整大小的数组,你应该使用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 . 这可以通过C ++算法实现,例如与ostringstream上使用的ostream_iterator一起copy

  5. No. If there was such a way, there wouldn't be any need for argc . 否。如果这样的方式,不会有任何需要argc EDIT: Apparently for argv only the final element of the array is a null pointer. 编辑:显然对于argv 只有数组的最后一个元素是一个空指针。

  1. char *argv[] can be read as: "an array of pointers to char" char *argv[]可以读作:“char的指针数组”

    char **argv can be read as: "a pointer to a pointer to char" char **argv可以读作:“指向char的指针”

  2. Yes, you may modify the argv array. 是的,您可以修改argv数组。 For example, argv[0][0] = 'H' will modify the first character of the first parameter. 例如, argv[0][0] = 'H'将修改第一个参数的第一个字符。 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) 如果通过“擦除/清除”你的意思是从数组中删除一个字符并且所有内容都自动切换:没有自动的方法 - 你需要将所有字符一个接一个地复制到左边(包括NULL终止)

  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? 你想如何将所有参数字符串表示为1 std :: string? It would make more sense to copy it to an array of std::strings 将它复制到std :: strings数组会更有意义

  5. No, there is no special indication of the last entry in the array. 不,没有特殊指示数组中的最后一个条目。 you need to use argc 你需要使用argc

  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). 它被称为“指向字符指针的指针数组”(请注意,这不是主函数的签名,它是int argc, char **argvint argc, char *argv[] - 这是等价的)。
  2. The argv array is modifiable (lack of const). argv数组是可修改的(缺少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. 你将以这种方式丢失信息 - argv是一个数组数组,因为各个参数已经为你分开了。 You could create a list of strings using std::list<std::string> args(&argv[1], &argv[argc]); 您可以使用std::list<std::string> args(&argv[1], &argv[argc]);创建字符串std::list<std::string> args(&argv[1], &argv[argc]); .
  5. Not really. 并不是的。 Most systems have argv NULL terminated, but that is not a guarantee. 大多数系统都有argv NULL终止,但这不是保证。

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 1)它应该是char **argvchar *argv[] ,它是a pointer to an array of characters通常称为an array of strings

2) CString is the std library to manipulate C strings (arrays of characters). 2) CString是操纵C字符串(字符数组)的std库。 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: 3)技术上没有,但是可以将它们删除然后重新分配:

int *array = new int[15]; //array of size 15
delete[] array;
array = new int[50]; //array of size 50

4) This is one way: 4)这是一种方式:

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: 5)是的,根据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." POSIX指定argv的最终空指针,例如参见“应用程序应确保此数组的最后一个成员是空指针”。 at pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html 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

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. C / C ++中的数组不是对象,而只是指向数组第一个元素的指针,因此您不能简单地删除或插入值。

Answering your questions: 回答你的问题:

  1. char *argv[] can be read as 'array of pointers to char ' char *argv[]可以读作' 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 通过手动将每个元素复制到std::string对象中
  5. No. 没有。

As a summary: C++ is much more low-level language that you think. 总结一下:您认为C ++是更低级的语言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM