トラック9・🔤文字列

string.h の主要関数

読む目安 約13分・ゴール:strlen・strcpy・strcat・strcmp の役割と使い方を説明できる

アプリでこのトピックを学ぶ(無料・登録不要)

このトピックの要点

文字列の操作は、#include <string.h> で使える標準関数が引き受けてくれます。まずは4つ、これだけ覚えれば大半の場面をしのげます。

関数役割
strlen文字数を数える('\0' は含まない)
strcpy文字列をコピーする
strcat文字列を後ろに連結する
strcmp2つの文字列を比べる
#include <stdio.h>
#include <string.h>

int main(void)
{
    char a[20] = "Hello";
    char b[20];

    printf("%zu\n", strlen(a));   // 5

    strcpy(b, a);                 // b は "Hello" になる
    strcat(b, ", C!");            // b は "Hello, C!" になる
    printf("%s\n", b);

    return 0;
}

strcpy も strcat も、第1引数が行き先です。strcat は行き先のヌル文字を探し、そこから続きを書き足して、最後に新しい '\0' を置きます。

関数の名前の読み方

str は string(文字列)の略です。strlen は string length、strcpy は string copy、strcat は string concatenate(連結)、strcmp は string compare。由来が分かると思い出しやすくなります。n の付く仲間(strncpy など)は「最大n文字まで」という制限付きの版で、次のトピックで扱います。

これらの関数はどれも '\0' を頼りに動きます。終端のない配列を渡せば、どの関数も配列の外まで走り続けます。「文字列関数に渡すものは、必ず終端されている」——これが暗黙の前提です。

比較は strcmp

文字列の比較は、初学者がいちばん驚くところかもしれません。

#include <stdio.h>
#include <string.h>

int main(void)
{
    char s[20] = "apple";

    if (strcmp(s, "apple") == 0) {      // 0 なら「等しい」
        printf("同じです\n");
    }

    printf("%d\n", strcmp("apple", "banana"));   // 負の値
    printf("%d\n", strcmp("banana", "apple"));   // 正の値
    return 0;
}

strcmp は「等しければ 0」を返します。真偽値ではないので、if (strcmp(a, b)) と書くと違うときに成立してしまいます。必ず == 0 を付けて、意図をはっきり書きましょう。

戻り値の符号には意味があります。負なら第1引数のほうが辞書順で前、正なら後ろ。この性質を使えば、名前の並べ替えもできます。

罠・注意

ビットstrcmp は「0が同じ」。ここだけは何度も間違えるから、指差し確認してね

まとめ: 数えるは strlen、写すは strcpy、つなぐは strcat、比べるは strcmp(0が等しい)。行き先の大きさは自分で保証します。

アプリでこのトピックを学ぶ(無料・登録不要)

確認問題

確認問題 1

2つの文字列が同じ内容かどうかを調べる、正しい書き方はどれですか。

  1. if (a == b)
  2. if (strcmp(a, b) == 0)
  3. if (strcmp(a, b))
  4. if (strlen(a) == strlen(b))
答えを見る

正解:B(if (strcmp(a, b) == 0))

strcmp は等しいとき 0 を返すので、== 0 で判定します。if (strcmp(a, b)) は「0以外=違うとき」に成立してしまう逆の条件です。== では中身を比較できず、長さが同じでも中身が同じとは限りません。

確認問題 2

次のプログラムの出力はどれですか。

#include <stdio.h>
#include <string.h>

int main(void)
{
    char a[20] = "Hello";
    char b[20];

    strcpy(b, a);
    strcat(b, ", C!");
    printf("%s %zu\n", b, strlen(b));
    return 0;
}
  1. Hello, C! 9
  2. Hello, C! 20
  3. Hello 5
  4. HelloC! 8
答えを見る

正解:A(Hello, C! 9)

strcpy で b は "Hello"、strcat で末尾に ", C!" が足されて "Hello, C!" になります。文字数は H e l l o , 空白 C ! の9文字です(strlen は '\0' を数えません)。

「文字列」の目次

  1. 文字列とはchar配列である
  2. ヌル終端 '\0' の掟
  3. 文字列リテラルと初期化
  4. string.h の主要関数
  5. 安全な文字列操作——バッファサイズの意識
  6. 文字の判定と変換(ctype.h)
  7. 文字コードの基礎——ASCIIとUTF-8
  8. 文字列処理の定石パターン

もっと先へ:ポインタ・メモリ・ファイル入出力・セキュアコーディングを含む全26トラックと、段位検定・模試のフルセットは完全版に収録しています。

完全版の販売ページは準備中です。

ほかのトラック

📚 姉妹教材:手を動かして覚える Linux 教材 — Linuxとインフラの仕組みを地図で学ぶ

Web版