2017-10-17 16 views
1

Cでパス2アセンブラを実装し、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); 
} 

はここで生成するトークンのコードで引数operandを変更することを許可されていない

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

問題があるとstrtok()が、それは最初の引数の変更、したがって、あなたのコードはundefined behaviorとなります。

関連の注意事項:

  • operand"THREE-3"リテラル文字列へのポインタです。

    引用C11、章§6.4.5

    [...]プログラムは、配列を変更しようとした場合、動作は未定義 あります。 strtok()動作の

  • 、チャプタ§7.24.5.8(強調鉱山

    からstrtok関数次いで 現在の区切り文字列に含まれる文字をそこから検索します。そのような文字が見つからない場合、現在のトークンは、s1が指し示す文字列の末尾の まで続き、トークンのそれ以降の検索ではNULL ポインタを返します。 このような文字が見つかった場合は、NULL文字で上書きされます。 は、現在のトークンを終了します。 strtok関数は次の 文字へのポインタを保存します。そこからトークンの次の検索が開始されます。

    つまり、strtok()は、最初の引数を変更します。

最も簡単な解決策は、operandアレイを作成し、次いでリテラル必要な文字列でそれを初期化し、strtok()の最初の引数として渡すことです。

3

変更

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

strtok

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

には、文字列を変更し、文字列リテラルを変更すると、未定義の動作です。

関連する問題