2015-06-24 151 views
3

我想用下面的代碼,但沒有索引陣列「[] []」,並與指針使用指針通過的argv迭代[]

for (int i = 0; i < argc; i++) { 
    for (int j = 0; argv[i][j] != '\0'; j++) { 
     //code 
    } 
} 

我知道,你可以使用指針代替它遍歷一個數組,但我不確定如何在第二個數組中使用未定義的長度來完成這個操作,在這種情況下,輸入是字符串。由於argv []的每個元素可以有不同的長度,我想確保能夠正確讀取字符並知道argv []的每個元素何時結束,並且下一個開始。

我希望它是這樣的:(如果下面的頭主要是不對的,請告訴我)

int main(int argc, char **argv) { 
    for (int i = 0; i < argc; i++) { 
     while(argv != '\0') { 
      //code 
      *argv+1; 
     } 
     //to skip null character 
     argv+1; 
    } 
} 
+2

你似乎認爲'argv'是連續的記憶塊。我不認爲這是一個安全的假設。 –

+1

@CareyGregory - 是對的。你不能簡單地假定下一個元素正好在空字節之後。但是你可以放心地假設每個元素都具有相同的大小,因此假定元素是從'argv'到'argv + argc - 1'是安全的。 – alvits

回答

4

由於for循環允許任何一種價值觀,不一定整數爲貴「的循環指數」,你的循環可能會被改寫這樣的:

for (char **a = argv ; a != argv+argc ; a++) { 
    for(char *p = *a ; *p != '\0' ; p++) { 
     // code uses *p instead of argv[i][j] 
    } 
} 

內環使用p作爲循環變量,這是增加與常規p++,並與*p != '\0'檢查。循環條件可以縮短到*p,所以內循環是這樣的:

for(char *p = *a ; *p ; p++) 
+0

你會如何消除argv [i]的索引?也許我應該刪除上面的循環,使其更加清晰。你寫的內容將會從argv [] []中讀取到每個單獨的子數組。由於它被視爲線性一維數組,因此我認爲應該可以在沒有argc的情況下迭代。其中一部分會找到行的末尾,所以外部循環將是「\ n」 –

+2

@BlakeLassiter誰說這是一個線性一維數組? –

+0

評論應該說*代碼使用\ * p而不是... * –

-1

請注意,所述的argv []本質上是一個指針數組,這意味着*(argv的+ I)將將i *指針大小添加到基本地址(在本例中爲argv),並將其威懾到一個指向字符串的指針。然後,你可以隨意操縱每個指針到一個字符串。下面的代碼是argv中打印出所有字符串的例子:

int main(int argc, char *argv[]){ 
    int i; 
    for(i = 0; i < argc; i++) 
     printf("%s\n", *(argv+i)); 
    return 0; 
} 
+1

這裏'for'循環的重點是什麼,它會在第一遍中遍歷所有'argv'。接下來的通行證會做什麼?段錯誤? – alvits

+0

感謝@alvits指出。我以前的答案中的while循環容易出錯。我已經更新了我的答案。 – lordofire

2

是的,你可以通過argv使用指針迭代。

內部循環告訴p指向argv+i的開始並遍歷它直到它達到\0

#include <stdio.h> 
int main(int argc, char **argv) { 
    int i; 
    char *p; 
    for(i=0; i < argc; i++) { 
     for(p=*(argv+i); *p; p++) 
      printf("%c", *p); 
     printf("\n"); 
    } 
} 

如果你只在遍歷每個參數感興趣,但在分析每個角色不感興趣,那麼你可以簡單。

#include <stdio.h> 
int main(int argc, char **argv) { 
    int i; 
    char *p; 
    for(i=0; i < argc; i++) { 
     printf("Argument position %d is %s\n", i, *(argv+i)); 
    } 
} 
1

你可以使用任何any_t *迭代任何any_t[],在這種情況下:

int main(int argc, char **argv) { 

    char **i = argv; //iterator of argv 
    char **e = argv + argc; //end of argv 

    for(; i != e; ++i) { 

    char *j = *i; //iterator of *i 

    //condition: *j mean *j != 0 
    for(; *j; ++j) { 
     printf("%c", *j); 
    } 

    printf("\n"); 

    } 

    return 0; 

} 
+0

很好的答案。但是OP要求''不''C++'。 – alvits

+0

@alvits我沒有注意到,謝謝 – DMaster

+0

@CareyGregory這只是一個嵌套循環的例子,注意問題是關於嵌套循環,而不是「如何打印序列」。我所做的是使用'printf'而不是'// code'行 – DMaster

2

鑑於在argv的最後一個元素是NULL,你不需要索引或用什麼比較如果你真的不想要,可以用argc

int main(int argc, char *argv[]) { 
    for (char **arg = argv; *arg; ++arg) { // for each arg 
    for (char *p = *arg; *p; ++p) {  // for each character 
     process(*p); 
    } 
    } 
} 

*argNULL在參數列表,這是假的結束。 *p將在每個字符串的末尾是'\0',這是錯誤的。

從N1256 5.1.2.2。1/2

如果它們被聲明,參數到主功能必須服從以下約束:

- 的argc的值應爲正數。

- argv [argc]應該是一個空指針。