2011-05-10 75 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只有數組的最後一個元素是一個空指針。