コピーしたいときに何を使うべきですかsrc_str
からdst_arr
なぜ?
char dst_arr[10];
char *src_str = "hello";
PS:良いまたは悪いがstrncpy
とstrlcpy
。
注:strlcpy
がどこでも利用できるわけではないことを私は知っています。ここではそれは問題ではありません。
strncpy
is never宛先文字列がゼロで終了している場合の正解。 strncpy
は、終了していないfixed-width文字列で使用することを目的とした関数です。より正確には、その目的は、(コピーによって)ゼロで終了する文字列を終了しない固定幅の文字列に変換することです。言い換えると、strncpy
はここでは意味のある適用はできません。
ここでの実際の選択は、strlcpy
とプレーンstrcpy
の間です。
_dst_arr
_への「安全な」(つまり、切り捨てられる可能性のある)コピーを実行する場合、使用する適切な関数はstrlcpy
です。
_dst_ptr
_...については「_dst_ptr
_にコピー」などはありません。 _dst_ptr
_が指すmemoryにコピーできますが、最初に、どこかを指していることを確認し、そのメモリを割り当てる必要があります。それを行うには多くの異なる方法があります。
たとえば、_dst_ptr
_を_dst_arr
_を指すようにすることができます。この場合、答えは前の場合と同じです-strlcpy
。
または、malloc
を使用してメモリを割り当てることができます。割り当てたメモリの量が文字列に対して十分であることが保証されている場合(つまり、少なくともstrlen(src_str) + 1
バイトが割り当てられている場合)、プレーンなstrcpy
またはmemcpy
を使用して文字列をコピーできます。この場合、strlcpy
を使用する必要はなく、使用する理由もありませんが、何らかの理由で安全性が増すため、使用することを好む人もいます。
意図的に割り当てるメモリを減らした場合(つまり、文字列を切り捨てたい場合)、strlcpy
が使用する適切な関数になります。
strlcpy()
はstrncpy()
より安全なので、使用した方がよいでしょう。
それを持たないシステムは、同じことをするs_strncpy()
を持っていることがよくあります。
注:何かを指すまでdst_ptr
に何もコピーできません
私はstrlcpyを知りませんでした。私はちょうど見つけました ここ それ:
Strlcpy()関数とstrlcat()関数は、それぞれ文字列をコピーして連結します。これらは、strncpy(3)およびstrncat(3)のより安全で一貫性があり、エラーが発生しにくい置換になるように設計されています。
したがって、strlcpyの縫い目はより安全です。
編集:完全な議論が利用可能です ここ 。
Edit2:
私が上で書いたことはあなたの質問の「あなたの場合」の部分に答えないことを私は理解します。 strncpyの制限を理解している場合は、それを使用して、落とし穴を回避するための適切なコードを記述できると思います。ただし、その制限についての理解がよくわからない場合は、strlcpyを使用してください。
Strncpyとstrlcpyの制限についての私の理解は、strncpy(バッファオーバーフロー)で非常に悪いことをすることができ、strlcpyでできる最悪のことは、その過程で1つの文字を失うことです。
常に標準関数(この場合はC11 strcpy_s()
関数)を使用する必要があります。 strncpy()
ではありません。これは安全ではなく、ゼロ終了を保証しないためです。また、OpenBSDのみのstrlcpy()
も安全ではないため、OpenBSDは常に独自の発明を考え出しますが、通常は標準にはなりません。
http://en.cppreference.com/w/c/string/byte/strcpy を参照してください
関数strcpy_sはBSD関数strlcpyに似ていますが、strlcpyがソース文字列を切り捨てて宛先に合わせる点が異なります(これはセキュリティ上のリスクです)。
Cライブラリにstrcpy_s
がない場合は、safeclibを使用してください。 https://rurban.github.io/safeclib/doc/safec-3.1/df/d8e/strcpy__s_8c.html