strncpy()
は、おそらくそれがないと思う何をしません。
strncat()
は、より安全なバージョンのstrcat()
で、ターゲット配列のサイズを指定できます。
strncpy()
は、ではなく、strcpy()
の対応する「より安全な」バージョンです。ターゲット配列が大きすぎる場合、strncpy()
はヌル文字で埋め込みます。文字列の末尾に1つの文字しか入力しない場合は、'\0'
とするだけで99%の時間が不要です。さらに悪いことに、ターゲット配列が小さすぎる場合、strncpy()
はできるだけ多くの文字をコピーし、をターゲットにして、末尾にのままにしておきます。
strncpy()
は、初期のUnixシステムがファイル名を格納するために使用するあいまいなデータ構造のために設計されています。ファイル名は、ヌルバイトが埋め込まれた固定長の14バイトバッファに格納されていました。ファイル名が正確に14文字の長さだった場合、ヌルターミネーターはありません。 これは文字列ではありません
それはあなたが欲しいデータ構造のようなものだとしたら、strncpy()
は単なるものです。それ以外の場合は、使用しないでください。ターゲットが十分に大きいことを確認してからstrcpy()
を使用してください。ここで
は、私は、この関数を書くかもしれない方法は次のとおりです。
void function(char *a, char *b)
{
char newStr[100];
/* Make newStr an empty string so you can concatenate onto it */
newStr[0] = '\0';
strncat(newStr, a, sizeof newStr - 1); /* edited */
strncat(newStr, b, sizeof newStr - strlen(newStr) - 1); /* edited */
/* Presumably you do something with newStr here */
}
注:
- 関数の戻り値の型を宣言します。明示的に宣言しないと、コンパイラはおそらくデフォルトで
int
になりますが、それはスタイルが悪くなり、古くなった言語機能です。
strncat()
を避けてください。
- 文字列をヌル終了させるために
'\0'
(NULL
ではなく)を使用しました。 NULL
はNULL ポインタ定数です。 NULL 文字を示すために使用しないでください。
かなりの非効率性がここにあります:strncat()
第二は、newStr
の先頭から再スキャンする必要があります。短い文字列の数が少ない場合は大したことではありませんが、多数の文字列が大きなターゲット配列に連結されると、深刻な減速を引き起こす可能性があります。この問題を回避する方法はありますが、非標準(strlcpy()
、strlcat()
)か不便です。
EDIT:私のコードでエラーを指摘してくれたMatthewに感謝します。私はだと思います。私はそれらを修正しました。私は、古いものを新しいものに置き換えれば、頭の中で私を殴ってくれる人に数えることができると確信しています。
選択肢は次のとおりです。
snprintf(newStr, sizeof newStr, "%s%s", a, b);
これはCで最も厄介な不満の一つでなければなりません - 'strncpy'は* *最後に書き込まれたバイト数またはポインタを返さないという事実が、むしろ最初のものへのポインタです(これは引数の1つなので、すでにわかっています)。 –
文字列を自分自身でヌル終了する必要があったとしても、NULLを使うのは間違いです。これはnull *ポインタ*定数です。ヌル文字は ''\ 0' '(または単に' 0')です。 –
@KerrekSB: 'strncpy'は、古くからの遺物で、' strcpy'の代わりに使われることは決してありませんでした。代わりに 'strlcpy'を使用してください。ただし、どこでも利用できません。 –