
C言語のきほん|文字列を比較する(strcmp、strncmp)
同じか違うかを、文字列の中身で正しく見分ける。strcmp と strncmp で比較の基本をしっかり身につけよう
C言語で文字列を扱うとき、2つの文字列が同じかどうかを調べたい場面はとても多くあります。
たとえば、入力されたユーザー名が正しいか確認したり、コマンド名が一致しているか判定したり、先頭の数文字だけが同じかを調べたりするときです。
ただし、C言語では整数や文字のように、文字列を == でそのまま比較することはできません。
ここが、C言語の文字列処理で最初につまずきやすいポイントのひとつです。
C言語の文字列は、文字列型として特別に扱われるのではなく、ナル文字 \0 で終わる文字の配列として扱われます。
そのため、見た目が同じ文字列かどうかを調べるには、先頭から順番に1文字ずつ比較していく必要があります。
その役割を担うのが、標準ライブラリ関数の strcmp と strncmp です。
strcmp は文字列全体を比較する関数です。
一方の strncmp は、先頭から指定した文字数だけ比較する関数です。
この2つを使えるようになると、
- 文字列全体が完全に一致しているか
- 先頭の何文字かだけ一致しているか
- どちらの文字列が文字コード順で大きいか
といったことを判定できるようになります。
この節では、strcmp と strncmp の基本的な使い方だけでなく、
- なぜ == では比較できないのか
- 比較結果としてどのような値が返るのか
- if 文でどのように判定するのか
- 先頭だけの比較はどんな場面で便利なのか
といった点まで、順番にやさしく見ていきます。
文字列比較は、入力チェックや条件分岐に欠かせないとても大切なテーマです。
ここでしっかり理解しておくと、今後の文字列処理がぐっとわかりやすくなります。
文字列を比較するとは
文字列を比較するとは、2つの文字列を先頭から順番に見比べて、同じかどうか、あるいはどちらが文字コード順で大きいかを調べることです。
たとえば、次のような比較を考えてみましょう。
| 文字列1 | 文字列2 | 判定 |
|---|---|---|
| cat | cat | 等しい |
| cat | car | 異なる |
| apple | apply | 異なる |
| ABCD | ABCC | 異なる |
| every | everyone | 先頭部分は同じ |
strcmp と strncmp は、どちらも先頭から1文字ずつ比較します。
そして、最初に異なる文字が見つかった時点で、その文字どうしの大小関係によって結果を決めます。
もし最後まで同じなら、等しいと判断して 0 を返します。
比較結果の返り値
strcmp 関数と strncmp 関数は、比較の結果を整数値で返します。
返却値の意味は次の通りです。
| 比較結果 | 返却値 |
|---|---|
| 文字列1 > 文字列2 | 正の値 |
| 文字列1 = 文字列2 | 0 |
| 文字列1 < 文字列2 | 負の値 |
ここでいう大小関係は、一般的には文字コード順です。
つまり、辞書順に似ていますが、実際には各文字のコード値に基づいて比較されています。
ASCII を前提にすると、小文字は大文字よりも大きい扱いになります。
たとえば A と a は同じアルファベットに見えますが、比較結果は等しいにはなりません。
| 文字1 | 文字2 | 一般的な判定 |
|---|---|---|
| A | a | A < a |
| B | A | B > A |
| a | b | a < b |
このあたりは、見た目の印象だけでなく、文字コード順で比較していると理解しておくことが大切です。
なぜ == で文字列比較できないのか
C言語では、文字列は文字型配列として扱われます。
そのため、文字列どうしを == で比べても、文字列の中身そのものを比較しているわけではありません。
たとえば、次のようなコードを考えてみます。
char s1[] = "abc";
char s2[] = "abc";見た目ではどちらも abc ですが、s1 と s2 は別々の配列です。
そのため、文字列の内容を比べたいなら、配列の中に入っている文字を順番に比べる必要があります。
この処理をしてくれるのが strcmp です。
つまり、C言語では
- 数値の比較は == でもできる
- 文字列の比較は strcmp 系の関数を使う
と整理して覚えるのが大切です。
strcmp 関数とは
strcmp は、2つの文字列全体を比較する関数です。
関数宣言
#include <string.h>
int strcmp(const char *s1, const char *s2);機能
s1 が指す文字列と s2 が指す文字列の大小関係を比較します。
返却値
| 条件 | 返却値 |
|---|---|
| 等しい | 0 |
| s1 が s2 より大きい | 正の整数値 |
| s1 が s2 より小さい | 負の整数値 |
使用例
char str1[] = "ABCD";
char str2[] = "ABCC";
int rc = strcmp(str1, str2);この場合、先頭から比べると 1文字目から3文字目までは同じですが、4文字目で D と C が異なります。
D のほうが C より大きいので、rc には正の値が入ります。
strcmp の比較の流れ
strcmp の動きは、次のように考えるとわかりやすいです。
たとえば、apple と apply を比較するとします。
| 比較位置 | 文字列1 | 文字列2 | 判定 |
|---|---|---|---|
| 1文字目 | a | a | 同じ |
| 2文字目 | p | p | 同じ |
| 3文字目 | p | p | 同じ |
| 4文字目 | l | l | 同じ |
| 5文字目 | e | y | 異なる |
この時点で、strcmp は e と y の大小関係を見て結果を返します。
つまり、strcmp は最初に違いが見つかった位置で判定を終える関数です。
strcmp の動きを図で理解する

この図では、2つの文字列が先頭から順に比較され、最初に異なる文字が見つかった時点で比較結果が決まることを表しています。
apple と apply は4文字目までは同じですが、5文字目の e と y で違いが出ます。
strcmp は、この違いを見つけたところで比較を終えます。
strncmp 関数とは
strncmp は、文字数を指定して比較する関数です。
文字列全体ではなく、先頭から n 文字までを比較したいときに使います。
関数宣言
#include <string.h>
int strncmp(const char *s1, const char *s2, size_t n);機能
s1 が指す文字列と s2 が指す文字列について、先頭 n 文字までの大小関係を比較します。
返却値
| 条件 | 返却値 |
|---|---|
| 等しい | 0 |
| s1 が s2 より大きい | 正の整数値 |
| s1 が s2 より小さい | 負の整数値 |
使用例
char str1[] = "ABCD";
char str2[] = "ABCC";
int rc = strncmp(str1, str2, 3);この場合、先頭3文字はどちらも ABC です。
そのため rc には 0 が代入されます。
もし 4文字まで比較すれば、4文字目で D と C が違うため、正の値になります。
strncmp が便利な場面
strncmp は、文字列全体ではなく、先頭部分だけ見たいときに便利です。
たとえば、次のような場面です。
| 使いどころ | 例 |
|---|---|
| 先頭数文字の一致確認 | every と everyone の先頭5文字を比較 |
| 接頭辞の判定 | Linux で始まるか確認 |
| 一部だけの比較 | 日付文字列の年だけ比べる |
| コマンド判定 | 先頭部分だけ共通かを見る |
たとえば、everything と everyone は全体では異なりますが、先頭5文字 every は同じです。
このような場合に strncmp が役立ちます。
strcmp と strncmp の違い
この2つの違いを表で整理すると、次のようになります。
| 項目 | strcmp | strncmp |
|---|---|---|
| 比較範囲 | 文字列全体 | 先頭から n 文字まで |
| 主な用途 | 完全一致の確認 | 先頭部分の一致確認 |
| 返却値 | 正の値、0、負の値 | 正の値、0、負の値 |
つまり、
- 文字列全体を比較したいなら strcmp
- 先頭部分だけ比較したいなら strncmp
と考えるとわかりやすいです。
strcmp と strncmp の使用例
ここでは、元のサンプルとは少し内容を変えた、シンプルで親しみやすい例を示します。
2つの単語を入力して、全体比較と部分比較を行うプログラムです。
表示メッセージも別の日本語表現に置き換え、コメントも日本語にしています。
ファイル名:12_7_1.c
#include <stdio.h>
#include <string.h>
int main(void)
{
char word1[100], word2[100];
int count;
printf("1つ目の単語を入力してください(最大99文字)> ");
scanf("%99s", word1);
printf("2つ目の単語を入力してください(最大99文字)> ");
scanf("%99s", word2);
/* strcmp で文字列全体を比較する */
if (!strcmp(word1, word2)) {
printf("2つの単語は同じです。\n");
} else {
printf("2つの単語は異なります。\n");
}
printf("先頭から比較する文字数を入力してください> ");
scanf("%d", &count);
/* strncmp で先頭から指定文字数だけ比較する */
if (!strncmp(word1, word2, count)) {
printf("先頭から%d文字は同じです。\n", count);
} else {
printf("先頭から%d文字は異なります。\n", count);
}
return 0;
}実行例
たとえば、次のように入力したとします。
1つ目の単語を入力してください(最大99文字)> morning
2つ目の単語を入力してください(最大99文字)> more
先頭から比較する文字数を入力してください> 3この場合、文字列全体としては異なります。
でも先頭3文字 mor は同じです。
そのため、表示は次のようになります。
2つの単語は異なります。
先頭から3文字は同じです。if (!strcmp(...)) の意味
ここも大事なポイントです。
if (!strcmp(word1, word2))この書き方は、最初は少し不思議に見えるかもしれません。
でも意味を分けて考えると簡単です。
strcmp の返却値は、
- 等しいとき 0
- 異なるとき 0以外
でした。
そして C言語では、
- 0 は偽
- 0以外は真
として扱われます。
さらに、論理否定演算子 ! を付けると、
- 0 は真になる
- 0以外は偽になる
ので、結果として
if (!strcmp(word1, word2))は「文字列が等しいなら実行する」という意味になります。
書き方の比較
| 書き方 | 意味 |
|---|---|
| if (strcmp(s1, s2) == 0) | 等しいとき実行 |
| if (!strcmp(s1, s2)) | 等しいとき実行 |
どちらも正しいです。
ただ、C言語では後者の書き方もよく使われます。
先頭比較のイメージを図で理解する

この図では、everything と everyone のように、全体は違っていても先頭部分が同じ場合をイメージしています。
strncmp は、指定した文字数までしか比較しないため、その範囲が同じであれば 0 を返します。
この性質によって、接頭辞の一致確認や一部分だけの比較がしやすくなります。
strcmp と strncmp を使うときの注意点
文字列比較では、次の点を意識しておくと混乱しにくくなります。
| 注意点 | 内容 |
|---|---|
| == では比較しない | 文字列比較には strcmp 系を使う |
| 等しいときは 0 | 真ではなく 0 が返る |
| 0以外は異なる | 正でも負でも「異なる」という意味になる |
| 大文字小文字は別 | Apple と apple は等しくない |
| strncmp は範囲限定 | 指定文字数までしか比較しない |
特に、「等しいときは 0」という点は逆に感じやすいですが、
「差がないから 0」と考えると覚えやすいです。
strcmp と strncmp を学ぶ意味
この2つの関数を使えるようになると、文字列を使った条件分岐がとても書きやすくなります。
たとえば、次のような処理に応用できます。
| 活用場面 | 内容 |
|---|---|
| ログイン判定 | 入力された文字列が登録値と一致するか確認 |
| コマンド判定 | 入力文字列が特定の命令か確認 |
| メニュー選択 | yes や no の入力を判定 |
| 接頭辞判定 | 先頭部分が特定の文字列か確認 |
文字列比較は、文字列処理の中でも特に実用性の高い基本機能です。
strcmp と strncmp をしっかり理解しておくと、この先のプログラム作成でも何度も役立ちます。
文字列比較を使いこなすための心構え
C言語の文字列比較では、見た目の印象だけでなく、返り値の意味を正しく理解して使うことが大切です。
特に意識したいのは次の点です。
| 心がけ | 内容 |
|---|---|
| 等しい判定は 0 を見る | strcmp の結果が 0 なら一致 |
| 用途で使い分ける | 全体比較なら strcmp、部分比較なら strncmp |
| 文字コード順を意識する | 大文字小文字の違いに注意する |
| if 文の書き方に慣れる | !strcmp や == 0 の意味を理解する |
strcmp と strncmp は、C言語の文字列処理の基本を支える大切な関数です。
この2つを使いこなせるようになると、入力された文字列を条件にした判定処理が、ぐっと書きやすくなります。
