• ベストアンサー

strtokでの空文字への置き換え

大したことじゃないと言えばそうかもしれませんが、ちょっと氣になるんで質問させてください。 C言語でstrtokという函數ありますよね。 第1引數の文字列を、第2引數の文字列を構成する文字で區切る。 第2引數の文字を見つけたら、それを空文字('¥0')に置き換える。 字句の最初の文字へのポインタを返す。 このようなものだと理解しています。 次のプログラムを實行してみました。 #include <stdio.h> #include <string.h> int main(void) { char string[]="XYZ1231ABC"; int i; printf("%s\n", string); putchar('\n'); printf("%s\n", strtok(string, "1A")); printf("%s\n", strtok(NULL, "1A")); printf("%s\n", strtok(NULL, "1A")); printf("%s\n", strtok(NULL, "1A")); putchar('\n'); for(i=0; i<=10; i++) printf("string[%d]=%c\n", i, string[i]); return 0; } 結果 XYZ1231ABC XYZ 23 BC (null) string[0]=X string[1]=Y string[2]=Z string[3]= string[4]=2 string[5]=3 string[6]= string[7]=A string[8]=B string[9]=C string[10]= 私が思うには、string[7]は空文字に置き換わってしまうはずだと思うんですが、 結果は'A'のままです。 ここが '¥0'に置き換わるかどうかは しょり系によって異なるのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • muyoshid
  • ベストアンサー率72% (230/318)
回答No.1

こんにちわ。 strtok 関数の動作についてですが、kmu_0031 さんの確認された結果で 全く問題ないと思います。 strtok は文字列を区切り文字で分割して、分割されたトークンのアドレス を返すだけですので、連続した区切り文字を見つけた時に全てをNULL文字に 置き換えるかどうかについてはライブラリの実装に任されている筈です。 実装がライブラリに任されている場合、極力効率良く (処理が軽くなるように) 実装されている筈です。 (余計な事をして性能を劣化させないように) 今回の場合、string[7] にNULL文字をセットしても、しなくても3回目の 呼び出しで"BC" へのポインタを返していますので、strtok の処理としては 全く問題がないと言えます。

noname#2823
質問者

お礼

>strtok は文字列を区切り文字で分割して、分割されたトークンのアドレス >を返すだけですので、連続した区切り文字を見つけた時に全てをNULL文字に >置き換えるかどうかについてはライブラリの実装に任されている筈です。 おっしゃることわかります。私が質問したことはstrtokの本質とは關係なさそうですね。 ありがとうございました。

その他の回答 (1)

  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.2

strtokは伝統的な(=Ritchie-C,Jhonson-C)C文字列ライブラリ(string)ではなく、White Smith-Cという方言色の強い処理系で実装されていた関数です。 White Smith-Cの独自関数はANSI-Cでほとんど駆逐されてしまったのですが、stringにstrtokやstrspnなどが残っています。 ってことで、strtokの挙動はPortable C Compiler(pcc)ライブラリから派生した他のANSI-Cライブラリ関数とは異質なことが多いようです。 (pccはポータビリティ確保のためトリッキーな内部処理を極力避けているため) で実装ですが、「インターフェース仕様がANSI-Cに適合していれば内部処理に関しては実装依存でかまわない」というのが実情です。 その他にmemoryなどのライブラリも実装依存です。 mallocやstdioなんかはOS依存部分を多く含むため「内部処理の挙動を想定してはいけない」というのが一般的な見解でしょう。

noname#2823
質問者

お礼

ご回答ありがとうございます。 どうも難しい話はよくわからないですが、 問題ないということですね。