Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
strlen() / strcpy() / strncpy()
文字列の長さを取得したり、別のバッファへコピーしたりする基本関数です。バッファサイズを超えた書き込みはセキュリティ上の重大な脆弱性になるため、境界の扱いに細心の注意が必要です。
構文
// 文字列の長さをヌル文字を除いたバイト数で返します。 size_t strlen(const char *s); // src の内容を dst にヌル文字ごとコピーします。 // dst と src のメモリが重なってはいけません。 char *strcpy(char *dst, const char *src); // src の最大 n バイトを dst にコピーします。 // src が n バイト未満の場合は残りをヌル文字で埋めます。 // src が n バイト以上の場合はヌル文字が付加されません(注意が必要です)。 char *strncpy(char *dst, const char *src, size_t n);
関数比較
| 関数 | バッファ保護 | ヌル終端保証 | 用途 |
|---|---|---|---|
| strcpy() | なし | あり | dst が十分大きいことが保証されている場合のみ使えます。 |
| strncpy() | あり(サイズ指定) | なし(n以内でも保証なし) | バッファサイズを制限できますが、ヌル終端を手動で付ける必要があります。 |
| strlcpy()* | あり(サイズ指定) | あり | BSD拡張。常にヌル終端を保証する安全な代替です(標準Cではありません)。 |
| snprintf() | あり(サイズ指定) | あり | 常にヌル終端を保証します。コピーにも使えます。 |
サンプルコード
#include <stdio.h>
#include <string.h>
int main(void) {
const char *src = "Hello, C!";
// strlen で文字列の長さを取得します(ヌル文字を含まない)。
printf("長さ: %zu\n", strlen(src)); // 『長さ: 9』と出力されます。
// strcpy でコピーします(dst のサイズが十分であることが前提です)。
char dst1[32];
strcpy(dst1, src);
printf("strcpy: %s\n", dst1); // 『strcpy: Hello, C!』と出力されます。
// strncpy でサイズを制限してコピーします。
char dst2[6];
strncpy(dst2, src, sizeof(dst2) - 1); // n に sizeof-1 を渡します。
dst2[sizeof(dst2) - 1] = '\0'; // 手動でヌル終端を保証します。
printf("strncpy(5): %s\n", dst2); // 『strncpy(5): Hello』と出力されます。
// snprintf はヌル終端を自動で行う安全なコピーに使えます。
char dst3[8];
snprintf(dst3, sizeof(dst3), "%s", src);
printf("snprintf: %s\n", dst3); // 『snprintf: Hello, 』と出力されます(7文字+'\0')。
return 0;
}
概要
strcpy() はコピー先バッファのサイズを一切チェックしません。src が dst より長い場合はバッファオーバーフローが発生し、隣接メモリを破壊してセキュリティ脆弱性になります。現代的なコードでは snprintf() を使うことが推奨されます。
strncpy() は n 文字以内に src が収まらない場合、ヌル終端を付加しません。必ず末尾を手動でヌル文字にする(dst[n-1] = '\0')か、snprintf() を代替として使ってください。
文字列の連結には『strcat() / strncat()』、比較には『strcmp()』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。