Reputation: 13
I'm implementing pass 2 assembler in C and trying to fetch the terms of an expression using strtok()
. The function is running inside the while
loop correctly but it is not generating the tokens properly.
Here is the code for generating tokens:
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);
}
This is the ouput:
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
Upvotes: 1
Views: 189
Reputation: 134326
The problem is the argument operand
is not allowed to be modified and strtok()
modifies it's first argument, so, your code causes undefined behavior.
Related notes:
operand
is a pointer pointing to the string literal "THREE-3"
.
Quoting C11
, chapter §6.4.5
[...] If the program attempts to modify such an array, the behavior is undefined.
for strtok()
behavior, from chapter §7.24.5.8 (emphasis mine)
The strtok function then searches from there for a character that is contained in the current separator string. If no such character is found, the current token extends to the end of the string pointed to by s1, and subsequent searches for a token will return a null pointer. If such a character is found, it is overwritten by a null character, which terminates the current token. The strtok function saves a pointer to the following character, from which the next search for a token will start.
which means, strtok()
modifies it's first argument.
The simplest solution is to make operand
an array and initialize it with the required string literal and then, pass it as the first argument to strtok()
.
Upvotes: 3
Reputation: 50775
Change
char *operand = "THREE-3"; // here operand points to a string literal
to
char operand[] = "THREE-3"; // here operand is an array of chars terminated by a NUL char
strtok
modifies the string, and modifying string literals is undefined behaviour.
Upvotes: 3