memcpy()
とstrcpy()
の違いは何ですか?私はプログラムの助けを借りてそれを見つけようとしましたが、どちらも同じ出力を提供しています。
int main()
{
char s[5]={'s','a','\0','c','h'};
char p[5];
char t[5];
strcpy(p,s);
memcpy(t,s,5);
printf("sachin p is [%s], t is [%s]",p,t);
return 0;
}
出力
sachin p is [sa], t is [sa]
この効果を見るためにできること
このコードをコンパイルして実行します。
_void dump5(char *str);
int main()
{
char s[5]={'s','a','\0','c','h'};
char membuff[5];
char strbuff[5];
memset(membuff, 0, 5); // init both buffers to nulls
memset(strbuff, 0, 5);
strcpy(strbuff,s);
memcpy(membuff,s,5);
dump5(membuff); // show what happened
dump5(strbuff);
return 0;
}
void dump5(char *str)
{
char *p = str;
for (int n = 0; n < 5; ++n)
{
printf("%2.2x ", *p);
++p;
}
printf("\t");
p = str;
for (int n = 0; n < 5; ++n)
{
printf("%c", *p ? *p : ' ');
++p;
}
printf("\n", str);
}
_
次の出力が生成されます。
_73 61 00 63 68 sa ch
73 61 00 00 00 sa
_
「ch」がmemcpy()
によってコピーされたが、strcpy()
ではコピーされなかったことがわかります。
strcpy
は、NUL('\0'
)文字を検出すると停止しますが、memcpy
は検出しません。 printfの%s
もNULで停止するため、ここでは効果は見られません。
strcpy
は、ソース文字列のヌルターミネータが見つかると終了します。 memcpy
には、サイズパラメータを渡す必要があります。両方の文字配列でヌルターミネータが見つかった後、printf
ステートメントが停止している場合は、t[3]
およびt[4]
もデータをコピーしました。
strcpy
は、ソースでNULLまたは '\ 0'文字が見つかるまで、ソースから宛先に文字を1つずつコピーします。
while((*dst++) = (*src++));
as memcpy
は、ソースのデータに関係なく、指定されたサイズnのソースから宛先にデータ(文字ではない)をコピーします。
ソースに文字以外が含まれていることがわかっている場合は、memcpy
を使用する必要があります。暗号化されたデータまたはバイナリデータの場合、memcpyが理想的な方法です。
strcpy
は推奨されないため、strncpy
を使用します。
s
文字列にヌル文字があるため、printf
はそれ以上何も表示しません。 p
とt
の違いは、文字4と5になります。p
には何もありません(ゴミになります)。t
には'c'
と'h'
があります。
主な違いは、memcpy()
は常に指定した正確なバイト数をコピーすることです。一方、strcpy()
は、NUL(別名0)バイトを読み取るまでコピーし、その後停止します。
strcpy
または'\0'
に遭遇すると、NULL
は停止しますmemcpy
は通常、コピーするデータを常にスキャンするstrcpy
よりも効率的です。テストプログラムの問題は、printf()
がnull終了_%s
_に遭遇すると、_\0
_への引数の挿入を停止することです。そのため、出力では、memcpy()
がc
とh
の文字もコピーしたことに気付いていないでしょう。
GNU _glibc-2.24
_)で、(x86の場合)strcpy()
はmemcpy(dest, src, strlen(src) + 1)
を呼び出すだけです。