|
> 実際に次のソースで試してみました。
> char cpydat[10]; /*strncpy用*/
> cpydat[0] = '\0';
これは不要です。strncpy は、cpydat[0] の値を参照しません。
> strncpy(cpydat, moji, sizeof(cpydat)-1);
cpydat[9] は、値がセットされません。
> printf( "strncpy:%s\n",cpydat,sizeof(cpydat)-1 );
sizeof(cpydat)-1 は、無意味です。
> strncpyのほうは、コピーする文字列が、指定文字数より
> 小さい文字列とき、残りのコピーされる側に対し、ヌルを指定文字数まで埋めますが、
埋めてほしいのなら、strncpy を使ってください。
> char moji[]="abcdefghijkl"; /*文字データ 12文字*/
>
> でやってみても、実行結果が、
>
> strncpy:abcdefghi
> 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x0
最後の 0x0 は偶然ですね。
> なぜstrncatのほうがよろしいのでしょうか?
> 私としては、問題なくちゃんとコピーされればよいのですが・・・。
strncpy は、
コピーする文字列が指定文字数より小さい場合、余計なことをします。
コピーする文字列が指定文字数より大きい場合、'\0' を付加せず、結果が文字列になりません。
> それとも、これは処理系に依存してしまう問題なのでしょうか?
処理系には依存しません。
なお、文字数を制限してコピーすることは、sprintf や sscanf でも出来ます。
void f0(char *s1, const char *s2) { strncpy(s1, s2, 9); }
void f1(char *s1, const char *s2) { strncpy(s1, s2, 9); s1[9] = '\0'; }
void f2(char *s1, const char *s2) { s1[0] = '\0'; strncat(s1, s2, 9); }
void f3(char *s1, const char *s2) { sprintf(s1, "%.9s", s2); }
void f4(char *s1, const char *s2) { sscanf(s2, "%9s", s1); }
void set(char *s) { memset(s, 0x23, 10); }
void dump(const char *s)
{
int i;
for (i = 0; i < 10; i++) printf(" %02x", s[i]);
puts("");
}
int main(void)
{
char s[10];
set(s); f0(s, "abc"); dump(s);
set(s); f1(s, "abc"); dump(s);
set(s); f2(s, "abc"); dump(s);
set(s); f3(s, "abc"); dump(s);
set(s); f4(s, "abc"); dump(s);
puts("---");
set(s); f0(s, "abcdefghijklm"); dump(s);
set(s); f1(s, "abcdefghijklm"); dump(s);
set(s); f2(s, "abcdefghijklm"); dump(s);
set(s); f3(s, "abcdefghijklm"); dump(s);
set(s); f4(s, "abcdefghijklm"); dump(s);
return 0;
}
|