C言語なら俺に聞け(入門篇) Part 29
at TECH
492:デフォルトの名無しさん
08/06/07 21:45:07
>>485
hoge() は配列 gyou に格納されている元になる文字列から2番目、3番目、5番目のトークンを切り出し、
s1 、s2 、s3 の指している先へコピーする。そこまではいい。問題は、その指している先の大きさが足りていないことにある。
この場合コピーする先は main() で宣言された s1[18] 、s2[3] 、s3[21] である。これらはメモリ上に連続して配置される。
そしてたぶん s2 に3番目のトークンをコピーしたときに、s2 の範囲を踏み越えて s3 にまで書き込んでしまった。
このとき hoge() の中で s2 を表示したときには正しくトークンが書き出される。しかし次に s3 に5番目のトークンが書き込まれる。
ここで、s3 の中にある、s2 から領域を踏み越えて書き込まれた文字列のシッポを塗りつぶしてしまった。
そうなると、全部の処理が収まって main() に戻ってきてから s1 、s2 、s3 を表示させると、当然トークンは壊れている。
文字列をコピーするときは、コピーする先の領域の大きさが十分かどうかが常に問題になる。
特に strtok() では、トークンの長さがどれだけなのか事前に予測しがたいために、さらに難しくなる。
万全に行うには、strtok() の戻り値を一旦保存した上で strlen() でトークンの長さを調べ、
必要な大きさの領域を malloc() などで割り付けて、そこにトークンをコピーする。もちろん使い終わったら free() する。
もし所定の大きさを越えたぶんは捨ててしまってもいいとするのなら、
strncpy() か strncat() か sprintf() を使って領域に入るぶんだけをコピーする。
もっとも、切り出したトークンに特段手を加えないなら、そもそも配列にコピーする必要もないかもしれない。
この場合は、単にトークンの先頭を示すポインタの値を記憶しておけばよい。
strtok() によって切り出される各トークンの本体は strtok() の中にあるのではなく、
最初の strtok() の呼び出しで第一引数に指定したポインタの指し示す先、
つまりトークンを切り出す元になる文字列( strtok() によって加工される)の中にあるからである。
ただし、そうやって切り出した一群のポインタの値を関数の外に持ち出すには、
ポインタのポインタ(ポインタの配列)を使う必要があることに注意すること。
次ページ続きを表示1を表示最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
5029日前に更新/203 KB
担当:undef