C 文字列操作 新しいページはコチラ
提供: yonewiki
(→文字列区切り文字分割) |
(→文字列区切り文字分割) |
||
791行: | 791行: | ||
− | strtok、_strtok_l、wcstok、_wcstok_l、_mbstok、_mbstok_l , strtok_s、_strtok_s_l、wcstok_s、_wcstok_s_l、_mbstok_s、_mbstok_s_l | + | strtok、_strtok_l、wcstok、_wcstok_l、_mbstok、_mbstok_l ,<br /> |
+ | http://msdn.microsoft.com/ja-jp/library/vstudio/2c8d19sb.aspx<br /> | ||
+ | strtok_s、_strtok_s_l、wcstok_s、_wcstok_s_l、_mbstok_s、_mbstok_s_l<br /> | ||
+ | http://msdn.microsoft.com/ja-jp/library/vstudio/ftsafwz3.aspx<br /> | ||
+ | |||
+ | |||
+ | 比較関数よりは少ないけど、やっぱりマルチバイト版、マルチバイト2バイト文字対応版、ワイド文字版、それに_sをつけた文字列長を指定するセキュア版と個別ロケール指定をする_lのロケール版があります。_l版についてはココまで使い方を触れてこなかったのですが、 | ||
+ | |||
+ | <syntaxhighlight lang="cpp"> | ||
+ | _locale_t locale; | ||
+ | locale = _tsetlocale(LC_ALL, _T("Japanese")); | ||
+ | </syntaxhighlight> | ||
+ | として、localeという変数に_locale_t型の値を_tsetlocaleの返り値として格納しておいたものを関数の最後の引数にします。<br /> | ||
+ | コマンドプロンプトで動作確認してるだけの段階でlocale変数を利用しても、文字化けしか起こせないと思うので、テキスト出力とかを覚えてから試してみるといいかもしれません。<br /> | ||
+ | |||
+ | |||
+ | strtok系の関数では主要な引数が2つで、第1引数には区切り文字を含んだ大元の文字列変数の先頭アドレスの値。第2引数には区切り文字の先頭アドレスの値。","のように文字列リテラルを直接指定することもできますし、複数の区切り文字を含めて",/"とすることもできます。このような文字列が格納されてる変数の先頭アドレスを含んだポインタ変数あるいは、アドレスを返す配列名を指定すること(結局ポインタ変数みたいなものですが…)ができます。第1引数の文字列は書き換え可能な変数でないと駄目です。const char[]="…"のように定義している書き換えできない変数を引数にするとエラーになります。なぜならば、この関数は第2引数で指定している区切り文字を発見したら、その文字が格納されているアドレス部分、配列要素部分の中身を文字列終端を意味する\0に書き換えるからです。つまり、第1引数は、元の状態ではなくなるので、あらかじめバックアップが必要ならコピーをして、保管しておかなければなりません。そして、区切り文字が見つかると先頭アドレスから\0に置き換えた部分までの文字列を返り値として処理を終了します。<br /> | ||
+ | |||
+ | |||
+ | え?1つ目以降の区切り文字の結果は?<br /> | ||
+ | |||
+ | |||
+ | そうですよね…。2回目の区切り文字探索以降について、この関数の使い方は特殊でして、最初の1回目の区切り文字探索時は上記に記述したような引数で良いのですが、2回目以降の区切り文字探索では第1引数にNULLを設定し、最初に探索した際に\0置き換えた区切り文字の次のアドレスから、第2引数で指定した区切り文字を探索します。それで見つかった区切り文字をまた\0に置き換えて、探索開始アドレスから、\0までの文字列を返り値として処理が終わります。<br /> | ||
+ | |||
+ | |||
+ | え?それ以降は?<br /> | ||
+ | |||
+ | |||
+ | そうですよね…。探索の結果、区切り文字がみつからなくなるまで、繰り返すようなプログラムにして、ひとつづつ掘り起こすという地味な処理になります。 | ||
+ | 結果を文字列配列に格納したい場合は、自分で文字列配列を準備して、順番に格納しなければならないのです。区切り文字が何回現れて、いくつの文字が区切られた文字列が返ってきたのかも知りたい場合は、自分で回数を記録する処理が必要になります。<br /> | ||
+ | |||
+ | |||
+ | Perlなら見つかった分だけ勝手に配列を作ってくれるような関数だったぞ!って思っている人もおられるかもしれませんが、C++ではそこまで便利な標準関数はないです。ご自分でどうぞお好きなように使って下さい。みたいな感じ?そういうことです。2回目以降で元の文字列を指定せず、NULLを指定することからも、察知できることですが、二つ以上の区切り文字を含めた文字列を交互に、作業することもできませんのであしからず。一つ目が終わってから次の文字列って感じです。不思議な仕組みですよね。想像するに、文字列の後ろからなんらかの文字が現れて次に現れる\0がトークン検索開始位置の文字列になってるのかもしれません。このあたりは実験してみることによってあきらかになるかと思います。 | ||
=='''文字列の型変換'''== | =='''文字列の型変換'''== |