🔤 文字列
🎯 strlen・strcpy・strcat・strcmp の役割と使い方を説明できる
文字列の操作は、#include <string.h> で使える標準関数が引き受けてくれます。まずは4つ、これだけ覚えれば大半の場面をしのげます。
#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引数のほうが辞書順で前、正なら後ろ。この性質を使えば、名前の並べ替えもできます。
罠・注意
strcpy と strcat は、行き先の配列に十分な余裕があるかを確認しません。溢れたら即座に重大事故です。この対策が次のトピックの主題です。strcat の行き先は、あらかじめ正しい文字列('\0' 付き)でなければいけません。初期化していない配列にいきなり strcat すると、どこに書き足されるか分かりません。strlen の戻り値は size_t という符号なしの型です。printf では %zu を使います。また strlen(s) - 1 は、空文字列のとき巨大な数になるので危険です。strcpy、1文字だけなら s[i] = 'x'; で十分です。関数を使うかどうかは目的で選びましょう。まとめ: 数えるは strlen、写すは strcpy、つなぐは strcat、比べるは strcmp(0が等しい)。行き先の大きさは自分で保証します。
文字列の終わりを示すために置かれる、値0の特殊な文字'\0'のこと。これが無いと、どこまでが文字列かコンピュータが判断できなくなる。strlenなどの関数は、この'\0'を目印にして文字列の長さを数えている。
もっと先へ:ポインタ・メモリ・ファイル入出力・セキュアコーディングを含む全26トラックと、段位検定・模試のフルセットは完全版に収録しています。