風で飛んでいくチラ裏

気ままに雑記メモ書き殴り。古い記事は別blogからの引っ越しなのでレイアウトがアレです。

strcpy, strncpy, strlcpy

strcpy(char *dst, const char *src)

dstのサイズよりsrcのほうが大きいとdstの後ろを壊すので使わない。

 


strncpy(char *dst, const char *src, size_t size)

size文字分コピーするので、dstのサイズを知っている場合、メモリを壊さないように書けるけど、 以下の性質があって以外と面倒。

  • srcの文字数がsize以上だった場合、ヌル止めされない
  • srcの文字数がsize未満だった場合、残りが全て\0で埋められる (これはまあ、別に)

ヌル止めの1バイトも節約したいぐらい厳しい状況ならこっちを使うこともあるかもね。取り扱う範囲全体でそれを意識した設計にしないとだめだけど(C標準の文字列制御関数すら迂闊に使えなくなるし)。


size_t strlcpy(char *dst, const char *src, size_t size)

srcからsize-1分dstにコピーして、必ずヌル止めする。sizeにsizeof(dst)をつっこめば、 必ずバッファを壊さない。ヌル止めもしてくれる。

戻り値はsrcの文字数。dstに実際に詰めた文字数ではない。

必ずヌル止めしてくれるので、dstにどれだけコピーできたかはstrlenで分かる。 戻り値とstrlenの結果を比較すると、全てコピーできたかの確認もできる。

len = strlcpy(dst, src, sizeof(dst));
if(len != strlen(dst){
    printf("コピーしっぱい");
}

BSDにはあるけど、GNU系には付いてない。GNUのコード方針に違反するそうで。 その辺は以下をどうぞ。

strlcpy - wikipedia

http://ja.wikipedia.org/wiki/Strlcpy

広告を非表示にする
(function(document){ var pres = document.getElementsByTagName("pre") for(var i=pres.length; i--; ){  var el = makeOl(pres[i]) pres[i].appendChild(el) } function makeOl(pre){ var ol = document.createElement("ol") , li = document.createElement("li") , df = document.createDocumentFragment() , br = pre.innerHTML.match(/\n/g) ol.className = "preLine" ol.setAttribute("role", "presentation") for(var i=br.length; i--; ){ var li2 = li.cloneNode(true) df.appendChild(li2) } ol.appendChild(df) return ol } })(document)