2017-10-17 74 views
1

我在C中實現了pass 2 assembler並試圖使用strtok()來獲取表達式的條件。該函數正確運行在while循環內,但它不會正確生成令牌。strtok()函數不正確地標記字符串

下面是用於生成令牌的代碼:

char *terms[50]; 
char *operand="THREE-3" 
char delimit[] = "+-\*"; 
int k = 0; 
terms[k] = strtok(operand,delimit); 
while(terms[k] != NULL) 
{ 
    printf("token [%d]=%s\n",k,terms[k]); 
    k++; 
    terms[k]=strtok(NULL,delimit); 
} 

這是輸出中:

token [0]=3 
token [0]=3 
token [0]=3 
token [0]=3 
token [0]=3 
token [0]=3 
token [0]=3 
token [0]=3 
token [0]=3 
token [0]=3 
token [0]=3 
token [0]=3 
token [0]=3 
token [0]=3 
token [0]=3 
token [0]=THREE 
token [1]=3 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 
token [0]=THREE 

回答

3

問題是參數operand不允許進行修改和strtok()修改它的第一個參數,所以,你的代碼導致undefined behavior

相關注意事項:

  • operand是一個指針指向字符串字面"THREE-3"

    引用C11,章§6.4.5

    [...]如果程序試圖修改這樣的陣列,該行爲是 未定義。

  • strtok()行爲,從章§7.24.5.8(重點煤礦

    然後strtok函數在從那裏搜索與包含在 當前分隔字符串的字符。如果找不到這樣的字符,則當前令牌擴展到由s1指向的字符串的 末尾,並且隨後對令牌的搜索將返回空指針 。 如果找到這樣的字符,它會被空字符覆蓋,該字符將終止當前令牌。 strtok函數會保存一個指向下面的 字符的指針,從該字符開始下一個令牌搜索。

    這意味着,strtok()修改它的第一個參數。

最簡單的解決方案是使operand陣列,並且與所需的字符串常量初始化它,然後,把它作爲第一個參數strtok()

3

變化

char *operand = "THREE-3"; // here operand points to a string literal 

char operand[] = "THREE-3"; // here operand is an array of chars terminated by a NUL char 

strtok修改字符串,修改字符串字面量是不確定的行爲。