2017-10-17 71 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修改字符串,修改字符串字面量是不确定的行为。