C 文字列操作 新しいページはコチラ

提供: yonewiki
移動: 案内, 検索
(文字列比較)
(文字列コピー)
154行: 154行:
  
 
=='''文字列コピー'''==
 
=='''文字列コピー'''==
文字列のコピー?なんでコピーするの?ってなりそうですけど、変数の代入みたいなものです。<br />
+
文字列のコピー?なんでコピーするの?ってなりそうですけど、変数の代入みたいなものです。元の文字列はとっておいて、コピーした方を加工するということです。あるいはその逆。紙のコピーだと原版が綺麗だけど、原版もコピーも同じだから…<br />
元の文字列はとっておいて、コピーした方を加工するということです。あるいはその逆。紙のコピーだと原版が綺麗だけど、原版もコピーも同じだから…<br />
+
 
a=13;<br />
 
a=13;<br />
 
b=a;<br />
 
b=a;<br />
167行: 166行:
 
http://msdn.microsoft.com/ja-jp/library/xdsywd25.aspx<br />
 
http://msdn.microsoft.com/ja-jp/library/xdsywd25.aspx<br />
 
http://msdn.microsoft.com/ja-jp/library/5dae5d43.aspx<br />
 
http://msdn.microsoft.com/ja-jp/library/5dae5d43.aspx<br />
また、例によってマルチバイト文字版strcpy、ワイド文字版wcscpy、マルチバイト2バイト文字認識版_mbscpy、セキュリティ強化版の_sサフィックスがあります。<br />
+
また、例によってマルチバイト文字版strcpy、ワイド文字版wcscpy、マルチバイト2バイト文字認識版_mbscpy、セキュリティ強化版の_sサフィックスがあります。_s無し版の引数はコピー先文字列変数先頭char型アドレス、コピー元文字列変数先頭char型アドレス(文字列の終端に\0があること)となっています。_mbscpyの引数は第一引数、第二引数共にunsigned charになっています。この微妙に使いにくい引数の異なり…。しょうがないのかなぁ。<br />
_s無し版の引数は<br />
+
 
コピー先文字列変数先頭char型アドレス、コピー元文字列変数先頭char型アドレス(文字列の終端に\0があること)<br />
+
 
となっています。_mbscpyの引数は第一引数、第二引数共にunsigned charになっています。この微妙に使いにくい引数の異なり…。しょうがないのかなぁ。<br />
+
そして、_s版は第2引数にコピー先文字列変数先頭char型アドレスの大きさを必要とします。_sが付かない関数で第二引数だったコピー元は第三引数にずれます。strncpyのようにcpyの前にnが付くパターンでマルチバイト文字版、ワイド文字版、マルチ2バイト文字対応版と更には_lサフィックスでロケール個別設定ができる関数があります。マルチバイト2バイト文字対応版にはバイト長を引数とするcpyの前にbが付いたものもあります。>
<br />
+
でも…マルチバイト2バイト文字対応文字ってもともと配列の要素一つに1バイトを格納しているから、バイト長で扱っても、要素数で扱っても変わらないから何が違うのか?よくわからない。_mbs系のcpy関数の利点ってなんだろう。このへんはまた今度、考えてみよう。
そして、_s版は第2引数にコピー先文字列変数先頭char型アドレスの大きさを必要とします。_sが付かない関数で第二引数だったコピー元は第三引数にずれます。<br />
+
strncpyのようにcpyの前にnが付くパターンでマルチバイト文字版、ワイド文字版、マルチ2バイト文字対応版と更には_lサフィックスでロケール個別設定ができる関数があります。<br />
+
マルチバイト2バイト文字対応版にはバイト長を引数とするcpyの前にbが付いたものもあります。<br />
+
でも…マルチバイト2バイト文字対応文字ってもともと配列の要素一つに1バイトを格納しているから、バイト長で扱っても、要素数で扱っても変わらないから<br />
+
何が違うのか?よくわからない。_mbs系のcpy関数の利点ってなんだろう。このへんはまた今度、考えてみよう。
+
 
全部で、<br />
 
全部で、<br />
 +
 
strcpy、wcscpy、_mbscpy , strcpy_s、wcscpy_s、_mbscpy_s ,<br />
 
strcpy、wcscpy、_mbscpy , strcpy_s、wcscpy_s、_mbscpy_s ,<br />
 
strncpy、_strncpy_l、wcsncpy、_wcsncpy_l、_mbsncpy、_mbsncpy_l , strncpy_s、_strncpy_s_l、wcsncpy_s、_wcsncpy_s_l、_mbsncpy_s、_mbsncpy_s_l<br />
 
strncpy、_strncpy_l、wcsncpy、_wcsncpy_l、_mbsncpy、_mbsncpy_l , strncpy_s、_strncpy_s_l、wcsncpy_s、_wcsncpy_s_l、_mbsncpy_s、_mbsncpy_s_l<br />
 
_mbsnbcpy、_mbsnbcpy_l , _mbsnbcpy_s、_mbsnbcpy_s_l <br />
 
_mbsnbcpy、_mbsnbcpy_l , _mbsnbcpy_s、_mbsnbcpy_s_l <br />
 
これだけあります。<br />
 
これだけあります。<br />
<br />
+
 
で、結局は_tcsncpy_sを使いなさいってことになります。Unicode設定ならワイド文字版で、文字列長に厳しい設定が必要なwcsncpy_sだね。
+
 
第二引数は配列の大きさ+終端\0のための要素1つ分。バイト数ではないです。<br />
+
で、結局は_tcsncpy_sを使いなさいってことになります。Unicode設定ならワイド文字版で、文字列長に厳しい設定が必要なwcsncpy_sだね。第二引数は配列の大きさ+終端\0のための要素1つ分。バイト数ではないです。動的に生成した変数の場合は配列の大きさが取得できないので、wcslen(_tcslen)のような文字列長取得関数を使って、戻ってきた値に\0の要素のために1を加算した値が良いです。<br />
動的に生成した変数の場合は配列の大きさが取得できないので、wcslen(_tcslen)のような文字列長取得関数を使って、戻ってきた値に\0の要素のために1を加算した値が良いです。<br />
+
 
<syntaxhighlight lang="cpp" line start="1">
 
<syntaxhighlight lang="cpp" line start="1">
 
#include <iostream>
 
#include <iostream>
249行: 243行:
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
という感じでしたね。無理やり_mbscpy関数を使ってみるとこんな感じですね。unsigned char型は宣言と同時にnew演算子の定義は出来ないようです。<br />
+
という感じでしたね。無理やり_mbscpy関数を使ってみるとこんな感じですね。unsigned char型は宣言と同時にnew演算子の定義は出来ないようです。const型のcharからはキャストできないから、結局は一度、strcpy_sを使って、char型の文字列に置き換えないといけないです。マルチバイト型の2バイト文字認識操作関数って結局は、char型と同じなので、文字数を数えるときはstrlenで数えないといけない。char型と_mbsxxx関数を行ったり来たりするだけです。<br />
const型のcharからはキャストできないから、結局は一度、strcpy_sを使って、char型の文字列に置き換えないといけないです。<br />
+
マルチバイト型の2バイト文字認識操作関数って結局は、char型と同じなので、<br />
+
文字数を数えるときはstrlenで数えないといけない。char型と_mbsxxx関数を行ったり来たりするだけです。<br />
+
 
出力結果は以下のとおり<br />
 
出力結果は以下のとおり<br />
 
<syntaxhighlight lang="cpp">
 
<syntaxhighlight lang="cpp">
317行: 308行:
 
 
 
</syntaxhighlight>
 
</syntaxhighlight>
と、4つの引数をとるように記述します。第4引数が出力する最大文字の配列数です。出力する文字数と考えることもできます。<br />
+
と、4つの引数をとるように記述します。第4引数が出力する最大文字の配列数です。出力する文字数と考えることもできます。マルチバイト文字の場合には出力する文字数を指定できるのは効果的で、先頭から何バイト目で区切れば日本語文字が分断されないかの判断もしてくれながらの出力となります。この出力する文字数をあえてバイト単位で指定する_mbsnbcpy_sもあります。ただし、コピー先の文字列の配列はstrlenのようなバイト数分で準備する必要があることに注意が必要です。出力文字数を指定する場合は文字列全体の長さではなく、指定した文字数で必要な文字列バイト数を算出しておいて、メモリを確保するように処理を記述するのが良いかもしれません。ここでは強制キャストを使いましたが、もともとの文字列がunsigned charとして定義されているものをコピーするときに_mbs系の文字列コピーを利用するというのが自然な使い方になります。<br />
マルチバイト文字の場合には出力する文字数を指定できるのは効果的で、先頭から何バイト目で区切れば日本語文字が分断されないかの判断も<br />
+
してくれながらの出力となります。この出力する文字数をあえてバイト単位で指定する_mbsnbcpy_sもあります。<br />
+
ただし、コピー先の文字列の配列はstrlenのようなバイト数分で準備する必要があることに注意が必要です。<br />
+
出力文字数を指定する場合は文字列全体の長さではなく、指定した文字数で必要な文字列バイト数を算出しておいて、メモリを確保するように<br />
+
処理を記述するのが良いかもしれません。<br />
+
ここでは強制キャストを使いましたが、もともとの文字列がunsigned charとして定義されているものをコピーするときに_mbs系の文字列コピーを<br />
+
利用するというのが自然な使い方になります。<br />
+
  
 
=='''文字列連結'''==
 
=='''文字列連結'''==

2013年12月10日 (火) 00:00時点における版



個人用ツール
名前空間

変種
操作
案内
ツールボックス