文字列関数

毎回自分でループを書かなくていい

前回は終端記号に当たるまで添字を進めて、文字数を自分で数えました。よく使う操作は標準ライブラリにそろっているので、実際には自分で書きません。文字列を扱う関数は string.h にまとまっています。

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

この章で覚えるのは3つだけです。長さを測る strlen、コピーする strcpy、比べる strcmp です。

strlen は終端記号を数えない

char name[20] = "Sato"; printf("%d\n", (int)strlen(name)); // 4

strlen が返すのは、終端記号の手前までの文字数です。ですから "Sato" なら 4 で、確保した箱の数である 20 ではありません。中身の長さと箱の大きさは別物という区別が、C の文字列でいちばん大事なところです。

戻り値の型は int ではなく size_t という符号なしの型なので、%d で出すときは (int) を付けて int に直します。第2章でやったキャストです。

strcpy は = の代わり

配列に文字列を入れられるのは宣言のときだけで、あとから = で入れることはできません。

char name[20]; name = "Sato"; // これはコンパイルエラー strcpy(name, "Sato"); // これが正しい

strcpy(コピー先, コピー元) の順で書きます。代入と同じで、左が受け取る側です。

危ないのは、コピー先の箱が足りない場合です。strcpy は入りきるかどうかを確かめずに、終端記号まで書き込み続けます。

char small[4]; strcpy(small, "Yamada"); // 4個の箱に7個ぶん書き込む。周りが壊れる

コンパイルは通ってしまうので、コピー先の大きさは自分で保証するしかありません。

strcmp は同じなら0

文字列どうしを == で比べても、中身は比べられません。strcmp を使います。

if (strcmp(name1, name2) == 0) { printf("同じ名前です\n"); }

返ってくるのは「同じかどうか」の真偽ではなく、辞書順でどちらが先かを表す数です。同じなら 0、name1 のほうが辞書順で前なら負、後ろなら正になります。0 が「同じ」というのは直感に反するので、if (strcmp(a, b)) と書くと意味が反転してしまいます。必ず == 0 を付けてください。

負や正の値そのものは処理系によって違うことがあるので、大小を見たいときは < 0> 0 で判定します。

では、3つの関数を使ってみましょう。

要件

  1. string.h を include する
  2. Satoの文字数は4です の形で2人ぶん表示する
  3. 名前が同じなら 2つの名前は同じです、違うなら 2つの名前は違います と表示する
  4. name1 を backup にコピーして 控えはSatoです の形で表示する

入出力例

main("") → "Satoの文字数は4です Suzukiの文字数は6です 2つの名前は違います 控えはSatoです"

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.c
学習モード

メモ

文字列関数

⌘S で保存