2011-05-10 76 views
7

C++新手在这里。我有一些基本的问题。 int main(int argc, char *argv[])(C++)关于语法的非常基本的问题

  1. char *argv[]应该如何读取(或向人类说出)?
  2. 是否可以清除/擦除此类数组中的特定内容(一个或多个)字符?如果是,如何?
  3. 数组可以调整大小吗?如果是,如何?
  4. 如何将argv[]的全部内容复制到单个std::string变量中?
  5. 是决定的单词argv[]数量/参数没有argc还有别的办法吗?如果是,如何? (*)

我会很感激数字2-5的解释(不是代码)。我会自己弄清代码(我通过这种方式学得更快)。

在此先感谢。

(*)我知道main(char *argv[])是非法的。我的意思是,是否有至少不涉及argc可言,就像下面的表达式的方式:

for(int i = 0; i < argc; ++i) { 
    std::cout << argv[i] << std::endl; 
} 

int i = 0;  
while(i < argc) { 
    std::cout << argv[i] << std::endl; 
    ++i; 
} 

或者

int i = 0; 
do { 
    std::cout << argv[i] << std::endl; 
    ++i; } while(i < argc); 
+0

它应该是char * argv [],而不是char ** argv []。它被读作“argv是指向char的指针数组” – 2011-05-10 13:54:55

+0

你的意思是'int main(int argc,char * argv [])' – 2011-05-10 13:55:25

+0

是的,对不起。现在已经修复了。问题#1可能不再有效。但我只是离开那里。 – Corellis 2011-05-10 13:57:54

回答

0

1)它应该是char **argvchar *argv[]这是a pointer to an array of characters更常称为an array of strings

2)CString是在std库操纵C字符串的字符(阵列)。无需重新分配你无法改变一个数组,但你可以通过索引引用它改变元素的内容:

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)技术上来讲是没有,但它们也可以被删除,然后重新分配:

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

4)这是一种方法:

string *myString; 
if(argc > 0) 
{ 
    myString = new string(argv[0]); 
    for(int i = 1; i < argc; ++i) 
     myString->append(argv[i]); 
} 

5)是,根据Cubbi:

POSIX指定最终空指针 为argv的,例如参见“的 应用应确保此数组的最后一个 构件是一个空 指针。“在 pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html

这意味着可以这样做:

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

实际上它不仅仅是POSIX,C++标准要求:“argv [argc]的值应为0.”在3.6.1 [basic.start.main]/2 – Cubbi 2011-05-10 14:15:43

+0

谢谢。尽管我希望你没有包含代码。你破坏了开启新语言难题的乐趣(对我来说是新的,顺便说一句)。 :) – Corellis 2011-05-14 17:10:30

+0

@Corellis对不起,我喜欢举例说明我所说的话不清楚,但我保证我没有告诉你可以做的所有事情来回答你所有的问题。有很多方法可以解决不同的问题。 – Chad 2011-05-14 20:10:50

0
  1. char *argv[]可以理解为:“指向字符的指针数组”

    char **argv可以解读为:“一个指向字符指针”

  2. 是的,你可以修改argv阵列。例如,argv[0][0] = 'H'将修改第一个参数的第一个字符。如果通过“擦除/清除”,您的意思是从阵列中移除一个字符,并且所有内容都会自动切换:没有自动的方法来执行此操作 - 您需要将所有字符一个接一个地复制到左侧(包括NULL终止)

  3. 不,数组不能调整大小。您将需要创建一个新的并复制内容

  4. 如何将所有参数字符串表示为1 std :: string?将它复制到一个std :: strings数组会更有意义

  5. 不,没有特别指示数组中最后一个条目。你需要使用argc

+0

我喜欢您对问题编号的回答。 2.希望SO允许我接受几个答案。 – Corellis 2011-05-14 17:13:26

2
  1. 它是指向字符数组。

  2. 排序 - 你可以覆盖它们。

  3. 只能复制到一个新的数组。

  4. 编写一个循环,并将每个argv [i]追加到C++字符串中。

  5. 大多数实现用NULL指针终止数组。我不记得这是否是标准的。

+1

字符串以NULL指针终止,但数组不是。 – Chad 2011-05-10 14:02:31

+0

不错的打字速度! POSIX为argv指定最终的空指针,例如参见“应用程序应确保该数组的最后一个成员是空指针。”在http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html – Cubbi 2011-05-10 14:02:35

+0

@Chad他们是如果有人(在这种情况下编译器实施者)在其中放置一个NULL。 – 2011-05-10 14:03:27

0
  1. 它读作“指针阵列的指针,以字符”(注意,这不是主要的功能,其是int argc, char **argvint argc, char *argv[]的签名 - 其等同)。
  2. argv数组是可修改的(缺少const)。超出其中一个字符串的末尾写入或扩展数组是非法的;如果你需要扩展一个字符串,创建它的一个副本并在数组中存储一个指针;如果您需要扩展数组,请创建数组的副本。
  3. 它们本身不能调整大小,但会被重新解释为更小的数组(这是解释最后一个问题的答案)。
  4. 您将以这种方式丢失信息 - argv是一个数组数组,因为单个参数已经为您分开。您可以使用std::list<std::string> args(&argv[1], &argv[argc]);创建一个字符串列表。
  5. 不是。大多数系统已终止,但这不是保证。
-1

阵列在C/C++是不是一个对象,而只是一个指针数组的第一元素,因此不能简单地删除或插入件。值

回答您的问题:

  1. char *argv[]可以理解为“指针数组char'
  2. 这是可能的,但涉及直接操纵存储器中的数据,例如复制和/或移动字节。
  3. 号但是你可以分配新的数组,并复制necesary数据
  4. 通过将每个元件手动复制到std::string对象

作为总结:C++是更低级的语言您认为。

+0

尽管在C和C++中数组本质上是相同的,但没有C/C++语言。在任何一种语言中,数组只是一个指针,尽管他们倾向于衰减为使用指针。在C99和C++中,'argv [argc]'保证是空指针,所以你可以用它来告诉'argv'的成员数目。 C++具有低级元素,主要来自C,但现代C++程序往往不会使用它们。 – 2011-05-10 14:19:28

1
char **argv[] 

是错误的。它应该是char **argvchar *argv[],而不是两者的混合物。然后它变成一个指向字符的指针,或者说是一个指向c字符串的指针,即一个c字符串数组。 :) cdecl.org在这样的事情上也很有帮助。
然后,对于访问,当然。就这样,访问它。 :) argv[0]将是第一个字符串,argv[3]将是第四个字符串。但我完全不会推荐替换不属于你的数组或者你知道内部数组的东西。
在数组上调整大小,因为您正在编写C++,请使用std::vector,它为您完成所有复杂的分配任务并且非常安全。一般来说,它取决于数组的类型。动态分配的数组(int* int_arr = new int[20])可以,静态数组(int int_arr[20])不能。
要将argv中的所有内容复制到一个std::string中,请遍历该数组,并将每个c-string附加到std::string。但我不会推荐,而是有一个std::vector<std::string>,即一个std::strings的数组,每个都持有一个参数。

std::vector<std::string> args; 
for(int i=0; i < argc; ++i){ 
    args.push_back(argv[i]); 
} 

在您的最后一个点,因为标准要求argv由一个NULL指针被终止,这是相当容易的。

int myargc = 0; 
char** argv_copy = argv; 
while(++argv_copy) 
    ++myargc; 

while(++argv_copy)将第一递增阵列的指针,让它指向下一个元素(例如,在第一次迭代之后,将在C-串#2(argv[1])点)。之后,如果指针的计算结果为假(如果它是NULL),那么循环刹车,并且你有你的myargc。 :)

+0

感谢您的详细解答。太糟糕了,我不能接受多个答案。 – Corellis 2011-05-14 17:11:32

1
  1. 几个选项:字符串指针数组或C字符串数组。

  2. 您可以指定特定字符来清除它们,也可以将其余的数组向前移动到“擦除”字符/元素。

  3. 正常的C风格的数组不能调整大小。如果您需要C++中的可调整大小的数组,您应该使用std::vector

  4. 您必须遍历每个项目并将它们附加到一个字符串。这可以用C++算法完成,如copy连同在ostringstream上使用的ostream_iterator

  5. 不会,如果有这样一种方式,就不会有任何需要argc。编辑:显然argv只有数组的最后一个元素是一个空指针。