« 成功本50冊「勝ち抜け」案内 | トップページ | デザインも考えてみる »

2008年2月13日 (水)

strncpy再び

なんか、poderosaって画面が描画されないバグがあるみたいですね。会社でコーディングしているとき、スクロールさせるとうまく画面が更新がされないのでストレスたまりまくりです。にう。puttyとか使った方がよいのかなー。

さて、strncpyについて、コードで再度考えてみます。そもそもstrncpyの仕様は。。

char * strncpy(char *p_dst, const char *p_src, size_t n)

1.p_srcが指し示すアドレスから始まるnバイトの領域(領域Aとする)を、
  p_dstが指し示すアドレスから始まる領域(領域Bとする)にコピーする
2.ただし、領域Aの途中に'\0'があった場合は、それ以降はコピーでは
  なく、領域Bに'\0'をnバイトになるまで書き込む
3.二つの領域が重なっている場合の動作は未定義
4.返り値はp_dstの指すアドレス。つまりコピー先

です。簡単に言うと、あるアドレスから始まるnバイトの領域を、別のアドレスにコピーするというだけの関数です。ただし、途中に'\0'があった場合の動きがちょっと変です。
なので、これを文字列を扱う関数だと思って不用意に使うと痛い目に遭います。

中身を明示するためにコードで実装してみると。。。

char * strncpy(char *p_dst, const char *p_src, size_t n)
{
    int i = 0;

    // nバイト分繰り返す
    for ( i = 0; i < n; i++){
        // p_srcからp_dstに1バイトずつコピー
        p_dst[i] = p_src[i];

        // もし、p_srcの領域に'\0'が見つかったらコピーはやめる
        if ( '\0' == p_src[i] ){
            break;
        }
    }

    // '\0'以降は、nバイトになるまで、'\0'を書き込む
    for (; i < n; i++){
        p_dst[i] = '\0';
    }
    return p_dst;
}

こんな感じでしょうか(例によって未コンパイル、未試験)。繰り返しになりますが、strncpyは'\0'を書き込むことを保証しないので、strncpyで文字列を扱う場合には、つぎのいずれかの条件を、使う側で保証してあげる必要があります。

  • p_dstからnバイトより先に'\0'があること(strncpyが触る範囲外で'\0'終端する)
  • p_srcからnバイト以内に'\0'があること(strncpyのコピーする範囲で'\0'終端する)

では、また。

|

« 成功本50冊「勝ち抜け」案内 | トップページ | デザインも考えてみる »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/207693/40105415

この記事へのトラックバック一覧です: strncpy再び:

« 成功本50冊「勝ち抜け」案内 | トップページ | デザインも考えてみる »