2014-11-22 87 views
1

我真的想知道接下來的一段代碼是怎麼回事。在函數解析中,*line++ = '\0';是什麼意思?是否等於line[i] = '\0'i++;將參數放入一個char數組中,代碼解釋

接下來,這是什麼*argv++ = line;在做什麼?它如何分配整個變量線我假設第一個argv [0],然後argv [1]等?那不會太長?

下一個,而只是跳過線陣列,直到它達到一個字。

現在,解析函數完成後,調用argv和argv *會做什麼?是* argv第一個參數?

在此先感謝,我真的需要了解的是:(

void parse(char *line, char **argv) 
{ 
    while (*line != '\0') { 
      while (*line == ' ' || *line == '\t' || *line == '\n') 
       *line++ = '\0'; 

      *argv++ = line;  

      while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n') 
       line++; 
    } 
    *argv = '\0'; 
} 

,並在主:

char line[1024];  
char *argv[64];  
while (1) { 
     .... 
     gets(line); 
     ... 
     parse(line, argv); 
+0

注意,使用'得到()'的計劃是危險的;你無法控制緩衝區溢出。第一種互聯網蠕蟲('莫里斯'蠕蟲)利用「獲取()」作爲其傳播方式之一。 C11標準下降'gets()';它不再是標準C的一部分。你應該假設它不存在,或者它包含'abort()',並且永遠不應該使用'gets()'。使用['fgets()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fgets.html)或 ['getline()'](http://pubs.opengroup.org/onlinepubs /9699919799/functions/getline.html)。 – 2014-11-22 23:35:53

回答

2

表達式*line++ = '\0';是直截了當的。正如有些人已經注意到的那樣,++運算符的優先級高於*運算符,因此可以將表達式加括號爲*(line++) = '\0';

line++運算符將求值爲當前值line,然後按行增加該值。因此*line++評估爲line當前指向的字符。分配意味着將空字節'\0'分配給當前位置,並且line增加超過此位置。這是一個速記:

*line = '\0'; 
line++; 

在的問題,你問:

是什麼*line++ = '\0';意思?是否等於line[i] = '\0'i++;

第一部分已經解決。第二部分或多或少是準確的;嚴格地說,它僅適用於首先分配i = 0;(因此在增量後i將爲1),或者如果您始終使用i來索引line而不更改line本身的值。該行*argv = '\0';線會因爲*argv更傳統的書面*argv = NULL;*argv = 0;

注意是char *,而不是一個字符。這不正式不正確; '\0'是一個整數常量零,因此是一個有效的空指針常量,但按照這種方式編寫它是常規的。

在給定的代碼:

void parse(char *line, char **argv) 
{ 
    while (*line != '\0') { 
      while (*line == ' ' || *line == '\t' || *line == '\n') 
       *line++ = '\0'; 

沒有必要扎普領先的空白;編寫line++就足夠了。建議使用isspace()isblank()也很誘人。我觀察到gets()(顯示在main()程序中並且不應該使用)的輸入從不包含換行符,所以在這種情況下換行符測試是多餘的。

  *argv++ = line; 

      while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n') 
       line++; 
    } 
    *argv = '\0'; 
} 

的想法是,如果輸入行是:

arguments about the meaning of life 

那麼以後,你可以讓所有的以下斷言的安全:

assert(strcmp(argv[0], "arguments") == 0); 
assert(strcmp(argv[1], "about") == 0); 
assert(strcmp(argv[2], "the") == 0); 
assert(strcmp(argv[3], "meaning") == 0); 
assert(strcmp(argv[4], "of") == 0); 
assert(strcmp(argv[5], "life") == 0); 
assert(argv[6] == 0); 

鑑於你在切入輸入線,考慮POSIX strtok_r()函數或微軟的strtok_s()(或者,如果最糟糕的是最壞的,strtok(),但使用strtok()需要非常小心 - 例如,調用此函數的代碼在進行呼叫時不能使用strtok())。

void parse(char *line, char **argv) 
{ 
    char *token = line; 
    char *extra; 

    while ((token = strtok_r(token, " \t\n", &extra)) != 0) 
    { 
     *argv++ = token; 
     token = 0; 
    } 
    *argv = 0; 
} 

這也可能是明智的重新設計功能報告許多(非空)的論點有多麼有:

int parse(char *line, char **p_argv) 
{ 
    char *token = line; 
    char *extra; 
    char **argv = p_argv; 

    while ((token = strtok_r(token, " \t\n", &extra)) != 0) 
    { 
     *argv++ = token; 
     token = 0; 
    } 
    *argv = 0; 
    return argv - p_argv; 
} 
1

*line++ = '\0'等於:

*line = '\0'; 
line++; 

它是用來以零結束字符串,因爲它應該在C中。

*argv++ = line旨在解析char **argv(指向char數組的指針)中提供的參數的下一個參數。

+0

表達式的擴展不正確。 – 2014-11-22 21:27:22

+0

@JonathanLeffler,那我該如何改正它? – syntagma 2014-11-22 21:33:37

+0

看到我的答案。 '* line ++ ='\ 0';'實際上是'* line ='\ 0'的縮寫;行++;' – 2014-11-22 21:37:31

1
char * line 

表示您得到一個指向char的指針。因此,讓我們清楚地表明

*line 

會得到你的實際角色(這就是所謂的提領) 那麼*line++ = '\0';做的是:

*line = '\0'; 
line++; 

所以這是一樣的line[i++] = '\0'

完全相同適用於* argv ++ = line;

注意 * line ++與(* line)++完全不同。

-1

++操作者的優先級高於*所以

*line++將導致指針line首先被inceremented。

line++; 

然後

*line++ = '\0'; 

argv是這裏的雙指針和*argv將指向line

*argv++ = line 

相同說明上述

+0

我還是不明白,argv看起來會是什麼樣子,例如'測試三分之二',它會如何工作?首先,會使* argv [0]指向'測試三分之二',然後是'二分之三'和第三到'第三',還是我錯了? – user3885166 2014-11-22 19:00:30

+1

發生什麼的解釋並不準確。 – 2014-11-22 21:27:06

0

實際上,因爲賦值運算符在++具有更高的優先級,然後*line++ = '\0';實際上等於:

*line = '\0'; 
*line++;   // Increment the pointer in sizeof(char) 

現在,關於你關於argv的問題,那麼請注意它被定義爲一個字符串數組。 *argv的類型是char*,它們與行的類型相匹配。分配*argv++ = line意味着將逐行指向的地址放在* argv(而不是字符串的完整副本),因此不會有太多寫入的風險(除非argv沒有足夠的元素來容納號碼線)。 最後,聲明*argv = '\0'可能標誌着我們剛到達字符串數組的末尾,以類似的方式結束字符串標記爲C.

+1

'++'的優先級非常高; '='的優先級很低。你的第一條語句(「因爲賦值操作符比'++'更高的優先級)因此是錯誤的,即使你對事件發生的後續解釋是正確的。 – 2014-11-22 21:24:31

+0

喬納森是正確的。在更新操作數之前獲取結果的值是按順序排列的。 – 2501 2014-11-23 09:50:44

相關問題