文字列関数: 安全と危険

比較に == は使えない。そして strcpy は爆弾である。

バッファオーバーフロー
用意した領域を超えて書き込み、メモリを破壊すること。
snprintf
サイズ指定付きで安全にフォーマット出力・文字列コピーを行う関数。
チェーンソーと安全カッター (Chainsaw vs Safety Cutter)

古い関数(strcpy, strcat)は「ガードのないチェーンソー」です。 切れ味は鋭いですが、勢い余って自分の足(他のメモリ領域)まで切断してしまうことがあります(バッファオーバーフロー)。 新しい関数(snprintf)は「ストッパー付きの安全カッター」です。「ここまでしか切らない(サイズ指定)」という制限機能がついているため、怪我をする心配がありません。

== は使えない

文字列は配列(つまりポインタ)なので、if (s1 == s2) と書くと、文字の中身ではなく「アドレスが同じか」 を比較してしまいます。中身を比較するには strcmp を使います。

標準ライブラリの闇

古いC言語の教科書には strcpystrcat が載っていますが、これらは「コピー先のサイズをチェックしない」 という致命的な欠陥があります。現代の実務コードでは使用禁止とされていることが多いです。

基本関数

Common Usage
// よく使う関数
char s1[] = "Apple";
char s2[] = "Banana";
// 長さ (strlen)
printf("%zu\n", strlen(s1)); // 5
// 比較 (strcmp) : == は使えない!
if (strcmp(s1, s1) == 0) {
printf("Same!\n");
}
// s1 < s2 なら負の値、逆なら正の値

危険な関数 (使用禁止)

以下は「バッファオーバーフロー製造機」です。テストやコンテスト以外では使わないでください。

Banned Functions
// ❌ 危険な関数たち (Museum of Horrors)
char buf[10];
strcpy(buf, "VeryLongString"); // バッファオーバーフロー!
strcat(buf, "...More"); // メモリ破壊!
gets(buf); // 最凶最悪。使用禁止。

実践テクニック

snprintf最強説

文字列のコピー、結合、数値からの変換など、すべて <code>snprintf</code> 1つで安全に行なえます。書き込む最大サイズを指定できるため、オーバーフローしません。

Safe Pattern
// ✅ 安全な関数 (Modern Standard)
char buf[10];
// サイズ指定付きで整形・コピー
snprintf(buf, sizeof(buf), "%s", "Text");
// strncpy はヌル終端保証がないので、snprintf推奨

演習課題

課題1: パスワード比較
パスワード(文字列)を入力させ、strcmpを使って "secret" と一致したら "Access Granted" と表示してください。

合格ライン

文字列比較に strcmp を使う理由を知っている
strcpy がなぜ危険か説明できる