C 文字列操作のソースを表示
新しいページはコチラ
移動:
案内
,
検索
※このページではC言語にも存在していたという意味で記事タイトルがC 文字列操作になっていますが、<br /> [[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br /> <br /> == '''文字列操作''' == 文字列のコピー、連結、比較、一致、区切り文字分割、探索、文字列長取得といった操作を文字列操作と呼びます。<br /> 上記のような操作はCRT関数として提供されているため、関数の使い方さえ覚えれば簡単に操作できます。<br /> 更に、文字列の型変換、文字コード変換、大文字小文字変換、半角文字、全角文字変換、ファイルパス操作、ファイル名操作<br /> 拡張子取得といった文字列操作の応用もプログラミングでは必要になってきますし、文字列の検索と置換、<br /> ファイルへの入出力といった操作までを習得すると概ねの操作ができるようになります。<br /> <br /> 上記のように日本語でまとめて言い換えるのは簡単ですが、一つ一つを実際にやってみるとなると、そう簡単でもありません。<br /> メモリに保管される文字列を操作するというのは、手続きが複雑です。<br /> コピーひとつにしても、どういった文字列を基にして、何文字目から何文字目までをコピーするのか?<br /> それにはどれくらいの大きさの文字列長があるのか?どういった変数に格納するのか?領域はちゃんと確保されているのか?<br /> 手続きがうまくいかなかった場合はどうするのか?と何気に細かいことを教えてあげないと動かないのがコンピュータです。<br /> コンピュータ側からすると、人間のようには解釈は出来ない、そのかわりわからないことがあれば、<br /> どんな地道なことをしててでも調べてやるから、コンピュータに指令するのに必要な情報をそろえてほしい。<br /> まとめては動作させれないけど、内部的にはひとつづつ着実にコピーして、最終的には全部をコピーしてくれる。<br /> なんだか新入社員のようにいちいち指示しないといけないけど、まぁ的確に指示をすればやる気だけはあって、こなしてくれる。<br /> 新入社員はほっといても成長しますが、コンピュータはほっとくと延々と成長しません。勝手にやってくれるようになるには、<br /> 勝手にやれるようになるための成長するプログラムが必要になります。偉い人たちは地道にやっているようです。<br /> <br /> 成長云々の件はここでは関係ありませんので、置いておくとして、文字列の操作をひとつづつやってみましょう。(書きかけの記事です。最終更新131128)<br /> 文字列操作に関する関数は以下のアドレスのとおりです。<br /> http://msdn.microsoft.com/ja-jp/library/f0151s4x.aspx<br /> 上記があれば、自分が説明する必要はもうないかなと思うわけですが、一応、自分なりに。<br /> =='''文字列長取得'''== http://msdn.microsoft.com/ja-jp/library/78zh94ax.aspx<br /> http://msdn.microsoft.com/ja-jp/library/z50ty2zh.aspx<br /> _tcslen(TCHA型設定時)/wcslen(Unicode設定)/strlen(マルチバイト設定)<br /> マルチバイト設定時の日本語対応関数 _mbslenになります。第一引数がNULLのとき、アクセス違反が発生します。<br /> <br /> lenの前にnが付くものは第二引数に最大文字数を設定する必要があり、文字列がそれを超えた場合は最大文字数を返します。<br /> _tcsnlen(TCHA型設定時)/wcsnlen(Unicode設定)/strnlen(マルチバイト設定) サフィックスに_sが付く関数では、第一引数がNULLときは戻り値が0になります。<br /> マルチバイト設定時の日本語対応関数 _mbsnlen<br /> <br /> _mbstrlenおよび_mbstrnlen は無効なマルチバイトを含む場合に戻り値-1を返します。<br /> _mbstrnlen は最大文字を超えると例外処理が発生し戻り値に-1とするとともにEINVAL に errnoを格納します。<br /> 更にサフィックスに_lが付くものは最後の引数として、ロケール設定ができます。ロケール設定の無い関数はsetlocale関数で設定された値に従います。<br /> <br /> 全部で<br /> strlen、strlen_l、wcslen、wcslen_l、_mbslen、_mbslen_l、_mbstrlen、_mbstrlen_l , strnlen、strnlen_s、strnlen_l、wcsnlen、wcsnlen_s、wcsnlen_l、_mbsnlen、_mbsnlen_l、_mbstrnlen、_mbstrnlen_l <br /> これだけの種類があります。<br /> <br /> 要するに?<br /> _tcslenを使うのが良いでしょう。Locale設定はあらかじめ実施しておくのが良いと思います。strnlen_sやwcsnlen_sはNULLの文字列の場合に0を返してくれるのはなんか良さげですが、<br /> 文字列の終端が必ず\0で終わっていさえすれば必要のないことです。それはヌル文字でもいいわけです。アドレスがヌルのヌルポインターのときにプログラムが止まるよって言ってます。<br /> なんか、いっぱいありすぎて迷うけど…。_tcslen!<br /> _lが付く関数は個別にLocale変換が必要な場合にのみ使えば良いでしょう。_tcsnlenで最大文字数を設定するのは、一見安全そうですが、なんか無駄なような気がします。<br /> あきらかに最大文字数がわかるような場合には、なんか入れておいて_tcsnlen_sってのはいい選択肢だと思います。<br /> <br /> <syntaxhighlight lang="cpp" line start="1"> #include <tchar.h> int main() { _tsetlocale(LC_ALL, _T("Japanese")); const TCHAR *cStr0[]={_T("表示:よねウィキの機能<yonewiki>"),_T("表示:よねウィキの機能1<yonewiki>"),_T("表示:よねウィキの機能2<yonewiki>")}; TCHAR **ppcStr0 = new TCHAR*[sizeof(cStr0)/sizeof(*cStr0)]; for(int i = 0; i < (sizeof(cStr0)/sizeof(*cStr0)); i++){ _tprintf(_T("%2d/%2d:cStr0[%2d]=%s\nStrCount=%d\n\n"),i, sizeof(cStr0)/sizeof(*cStr0),i, cStr0[i],_tcslen(cStr0[i])); } } </syntaxhighlight> 出力結果 <syntaxhighlight lang="cpp"> 0/ 3:cStr0[ 0]=表示:よねウィキの機能<yonewiki> StrCount=21 1/ 3:cStr0[ 1]=表示:よねウィキの機能1<yonewiki> StrCount=22 2/ 3:cStr0[ 2]=表示:よねウィキの機能2<yonewiki> StrCount=22 </syntaxhighlight> _mbslenは文字列長探索をしたい文字列変数の引数が、unsigned char型ですので、<br /> wchar_t型、char型の引数では文字列長を探索することは出来ません。あえて実施するならば、<br /> reinterpret_cast<unsigned char*>(※charポインタ型※)と強制的なキャストを実施することで、動作させることができます。<br /> _mbstrlenはchar型を引数にしますので、wchar_t型を使わない場合の日本語文字列長検索として使うことが出来ます。<br /> 但し、この強制キャストは定数文字列const宣言のある文字列に対しては操作が出来ないため、文字列のコピーを作成する必要があります。<br /> 文字列コピー操作の詳細は次の項目に記載予定なので、順番に読み進めている人は、コピー操作について理解してから戻ってきた方が良いかもしれません。<br /> <syntaxhighlight lang="cpp" line start="1"> #include <tchar.h> int main() { _tsetlocale(LC_ALL, _T("Japanese")); const char *cStr1[]={"", "表示:よねウィキの機能<yonewiki>", "表示:よねウィキの機能1<yonewiki>", "表示:よねウィキの機能2<yonewiki>"}; char **ppcStr1 = new char* [sizeof(cStr0)/sizeof(*cStr0)]; _tprintf(_T("const マルチバイト文字→マルチバイト文字コピー→_mbslen関数2バイト文字認識文字列長探索\n")); for(int i = 0; i < (sizeof(cStr0)/sizeof(*cStr0)); i++){ ppcStr1[i] = new char[strlen(cStr0[i]) + 1];//まずは単純に文字列をコピーするための領域を確保。 strcpy_s(ppcStr1[i], strlen(cStr0[i]) + 1,cStr0[i]); } for(int i = 0; i < (sizeof(cStr0)/sizeof(*cStr0)); i++){ printf("%2d/%2d:cStr0[%2d]=%s\nStrCount=%d\n\n",i, sizeof(cStr0)/sizeof(*cStr0),i, cStr0[i],_mbslen(reinterpret_cast<unsigned char*>(ppcStr1[i]))); } } </syntaxhighlight> という具合にして、const char→char→_mabslenで文字列長探索が出来ます。<br /> 出力結果は以下のとおりです。<br /> <syntaxhighlight lang="cpp"> const マルチバイト文字→マルチバイト文字コピー→_mbslen関数2バイト文字認識文字列長探索 0/ 4:cStr2[ 0]= StrCount=0 1/ 4:cStr2[ 1]=表示:よねウィキの機能<yonewiki> StrCount=21 2/ 4:cStr2[ 2]=表示:よねウィキの機能1<yonewiki> StrCount=22 3/ 4:cStr2[ 3]=表示:よねウィキの機能2<yonewiki> StrCount=22 </syntaxhighlight> _mbstrlen関数を使う場合はコピー操作が必要にならず、const宣言している文字列変数を使っての文字列長探索ができます。<br /> <syntaxhighlight lang="cpp" line start="1"> #include <tchar.h> int main() { _tsetlocale(LC_ALL, _T("Japanese")); const char *cStr1[]={"", "表示:よねウィキの機能<yonewiki>", "表示:よねウィキの機能1<yonewiki>", "表示:よねウィキの機能2<yonewiki>"}; char **ppcStr1 = new char* [sizeof(cStr0)/sizeof(*cStr0)]; _tprintf(_T("const マルチバイト文字→_mbstrlen関数2バイト文字認識文字列長探索\n")); for(int i = 0; i < (sizeof(cStr0)/sizeof(*cStr0)); i++){ printf("%2d/%2d:cStr0[%2d]=%s\nStrCount=%d\n\n",i, sizeof(cStr0)/sizeof(*cStr0),i, cStr0[i],_mbstrlen(cStr0[i])); } } </syntaxhighlight> 出力結果は以下のとおりです。<br /> <syntaxhighlight lang="cpp"> const マルチバイト文字→_mbstrlen関数2バイト文字認識文字列長探索 0/ 4:cStr2[ 0]= StrCount=0 1/ 4:cStr2[ 1]=表示:よねウィキの機能<yonewiki> StrCount=21 2/ 4:cStr2[ 2]=表示:よねウィキの機能1<yonewiki> StrCount=22 3/ 4:cStr2[ 3]=表示:よねウィキの機能2<yonewiki> StrCount=22 </syntaxhighlight> *コピー *連結 *比較 *一致 *区切り文字分割 *探索 *正規表現 regex_match *文字列の型変換 *文字コード変換 *大文字小文字変換 *半角文字全角文字変換 *ファイルパス操作 *ファイル名操作 *拡張子取得 *文字列の検索と置換 *ファイルへの入出力 <!-- {|class="wikitable" !上位ビッツ\下位ビッツ!!0!!1!!2!!3!!4!!5!!6!!7!!8!!9!!A!!B!!C!!D!!E!!F |- |0||NUL||SOH||STX||ETX||EOT||ENQ||ACK||BEL|||BS||HT||LF||VT||FF||CR||SO||SI |- |1||DLE||DC1||DC2||DC3||DC4||NAK||SYN||ETB||CAN||EM||SUB||ESC||IS4||IS3||IS2||IS1 |- |2||SP||!||"||#||$||%||&||'||(||)||*||+||,||-||.||/ |- |3||0||1||2||3||4||5||6||7||8||9||:||;||<||=||>||? |- |4||@||A||B||C||D||E||F||G||H||I||J||K||L||M||N||O |- |5||P||Q||R||S||T||U||V||W||X||Y||Z||[||\||]||^||_ |- |6||`||a||b||c||d||e||f||g||h||i||j||k||l||m||n||o |- |7||p||q||r||s||t||u||v||w||x||y||z||{|| | ||} ||~||DEL |- |} {|class="wikitable" !上位ビッツ\下位ビッツ!!0!!1!!2!!3!!4!!5!!6!!7!!8!!9!!A!!B!!C!!D!!E!!F |- |8||||||BPH||NBH||||NEL||SSA||ESA||HTS||HTJ||VTS||PLD||PLU||RI||SS2||SS3 |- |9||DCS||PU1||PU2||STS||CCH||MW||SPA||EPA||SOS||||SCI||CSI||ST||OSC||PM||APC |- |A||||。||「||」||、||・||ヲ||ァ||ィ||ゥ||ェ||ォ||ャ||ュ||ョ||ッ |- |B||ー||ア||イ||ウ||エ||オ||カ||キ||ク||ケ||コ||サ||シ||ス||セ||ソ |- |C||タ||チ||ツ||テ||ト||ナ||ニ||ヌ||ネ||ノ||ハ||ヒ||フ||ヘ||ホ||マ |- |D||ミ||ム||メ||モ||ヤ||ユ||ヨ||ラ||リ||ル||レ||ロ||ワ||ン||゙||゚ |- |E|||||||||||||||||||||||||||||||| |- |F|||||||||||||||||||||||||||||||| |- -->
C 文字列操作
に戻る。
個人用ツール
ログイン
名前空間
ページ
議論
変種
表示
閲覧
ソースを表示
履歴表示
操作
検索
案内
メインページ
コミュニティ・ポータル
最近の出来事
最近の更新
おまかせ表示
ヘルプ
ツールボックス
リンク元
関連ページの更新状況
特別ページ