[C言語] if文での文字列比較方法

C言語で文字列を比較する際には、if文で直接比較演算子==!=を使うことはできません。

これは、文字列が配列として扱われ、比較演算子ではポインタのアドレスを比較してしまうためです。

文字列の内容を比較するには、標準ライブラリのstrcmp関数を使用します。

strcmpは2つの文字列を引数に取り、同じ場合は0を返し、異なる場合は正または負の値を返します。

したがって、if (strcmp(str1, str2) == 0)のようにして文字列が等しいかどうかを確認します。

この記事でわかること
  • C言語での文字列の基本的な扱い方と、ポインタと配列の違い
  • strcmp関数の基本的な使い方と返り値の意味
  • 文字列比較におけるNULLポインタや大文字小文字の違い、マルチバイト文字の扱い方
  • 大文字小文字を無視した比較や部分文字列の比較、文字列のソート方法

目次から探す

文字列比較の基本

C言語における文字列の扱い

C言語では、文字列は文字の配列として扱われます。

文字列は通常、char型の配列として定義され、文字列の終端にはヌル文字\0が必要です。

以下に基本的な文字列の定義方法を示します。

#include <stdio.h>
int main() {
    char greeting[] = "こんにちは"; // 文字列リテラルを配列として定義
    printf("%s\n", greeting); // 文字列を出力
    return 0;
}

この例では、greetingという配列に「こんにちは」という文字列を格納しています。

printf関数を使って、文字列を出力しています。

ポインタと配列の違い

C言語では、文字列を扱う際にポインタと配列の違いを理解することが重要です。

配列はメモリ上に連続して配置された要素の集合であり、ポインタはメモリ上のアドレスを指し示す変数です。

スクロールできます
配列ポインタ
メモリ上に連続して配置メモリ上のアドレスを指す
サイズが固定サイズが可変
sizeofで全体のサイズを取得sizeofでポインタのサイズを取得

以下に、配列とポインタの違いを示す例を示します。

#include <stdio.h>
int main() {
    char array[] = "配列";
    char *pointer = "ポインタ";
    printf("配列: %s\n", array);
    printf("ポインタ: %s\n", pointer);
    return 0;
}

この例では、arrayは配列として定義され、pointerは文字列リテラルを指すポインタとして定義されています。

文字列リテラルの特性

文字列リテラルは、プログラム中で直接記述される文字列です。

これらは通常、読み取り専用のメモリ領域に格納されます。

文字列リテラルを変更しようとすると、未定義の動作を引き起こす可能性があります。

#include <stdio.h>
int main() {
    char *str = "変更不可";
    // str[0] = '変'; // これは未定義の動作を引き起こす可能性がある
    printf("%s\n", str);
    return 0;
}

この例では、strは文字列リテラルを指すポインタです。

str[0]を変更しようとすると、プログラムの動作が未定義になる可能性があります。

文字列を変更する必要がある場合は、char型の配列を使用することが推奨されます。

strcmp関数の使い方

strcmp関数の基本構文

strcmp関数は、C言語の標準ライブラリで提供されている文字列比較のための関数です。

この関数は、2つの文字列を引数として受け取り、それらを辞書順で比較します。

strcmp関数の基本構文は以下の通りです。

#include <string.h>
int strcmp(const char *str1, const char *str2);

この関数は、str1str2を比較し、その結果を整数値で返します。

strcmp関数の返り値の意味

strcmp関数の返り値は、以下のように解釈されます。

スクロールできます
返り値意味
0str1str2が等しい
負の値str1str2より辞書順で前にある
正の値str1str2より辞書順で後にある

この返り値を利用して、文字列の比較結果を判断することができます。

strcmp関数を用いたif文の例

strcmp関数を用いて、文字列を比較する際のif文の例を以下に示します。

#include <stdio.h>
#include <string.h>
int main() {
    char *str1 = "apple";
    char *str2 = "banana";
    if (strcmp(str1, str2) == 0) {
        printf("文字列は等しいです。\n");
    } else if (strcmp(str1, str2) < 0) {
        printf("'%s'は'%s'より辞書順で前にあります。\n", str1, str2);
    } else {
        printf("'%s'は'%s'より辞書順で後にあります。\n", str1, str2);
    }
    return 0;
}

この例では、str1str2strcmp関数で比較し、その結果に応じて異なるメッセージを出力します。

str1str2より辞書順で前にある場合、"apple""banana"より前にあると出力されます。

strcmp関数を用いることで、文字列の比較を簡潔に行うことができます。

文字列比較の注意点

NULLポインタの扱い

strcmp関数を使用する際に、NULLポインタを渡すと未定義の動作を引き起こす可能性があります。

NULLポインタは有効な文字列を指していないため、strcmp関数で比較する前に、ポインタがNULLでないことを確認する必要があります。

#include <stdio.h>
#include <string.h>
int main() {
    char *str1 = NULL;
    char *str2 = "example";
    if (str1 != NULL && strcmp(str1, str2) == 0) {
        printf("文字列は等しいです。\n");
    } else {
        printf("文字列は等しくないか、str1がNULLです。\n");
    }
    return 0;
}

この例では、str1がNULLであるため、strcmp関数を呼び出す前にNULLチェックを行っています。

大文字と小文字の違い

strcmp関数は大文字と小文字を区別して比較します。

したがって、”Apple”と”apple”は異なる文字列として扱われます。

大文字小文字を無視して比較したい場合は、strcasecmp関数(POSIX標準)を使用することができます。

#include <stdio.h>
#include <strings.h> // strcasecmpを使用するためのヘッダ
int main() {
    char *str1 = "Apple";
    char *str2 = "apple";
    if (strcasecmp(str1, str2) == 0) {
        printf("大文字小文字を無視して文字列は等しいです。\n");
    } else {
        printf("大文字小文字を無視して文字列は等しくないです。\n");
    }
    return 0;
}

この例では、strcasecmp関数を使用して、大文字小文字を無視して文字列を比較しています。

マルチバイト文字の比較

日本語などのマルチバイト文字を扱う場合、strcmp関数は正しく動作しないことがあります。

これは、strcmp関数がバイト単位で比較を行うためです。

マルチバイト文字を正しく比較するには、wchar_t型を使用し、wcscmp関数を利用することが推奨されます。

#include <stdio.h>
#include <wchar.h> // wcscmpを使用するためのヘッダ
int main() {
    wchar_t *str1 = L"こんにちは";
    wchar_t *str2 = L"こんばんは";
    if (wcscmp(str1, str2) == 0) {
        printf("マルチバイト文字列は等しいです。\n");
    } else {
        printf("マルチバイト文字列は等しくないです。\n");
    }
    return 0;
}

この例では、wchar_t型を使用して日本語の文字列を定義し、wcscmp関数で比較しています。

これにより、マルチバイト文字を正しく比較することができます。

応用例

大文字小文字を無視した比較

大文字小文字を無視して文字列を比較する場合、strcasecmp関数を使用することができます。

この関数は、POSIX標準で提供されており、strcmp関数と同様に2つの文字列を比較しますが、大文字小文字の違いを無視します。

#include <stdio.h>
#include <strings.h> // strcasecmpを使用するためのヘッダ
int main() {
    char *str1 = "Hello";
    char *str2 = "hello";
    if (strcasecmp(str1, str2) == 0) {
        printf("大文字小文字を無視して文字列は等しいです。\n");
    } else {
        printf("大文字小文字を無視して文字列は等しくないです。\n");
    }
    return 0;
}

この例では、strcasecmp関数を使用して、”Hello”と”hello”を大文字小文字を無視して比較しています。

部分文字列の比較

部分文字列を比較する場合、strncmp関数を使用することができます。

この関数は、指定した長さまでの文字列を比較します。

#include <stdio.h>
#include <string.h>
int main() {
    char *str1 = "abcdef";
    char *str2 = "abcxyz";
    if (strncmp(str1, str2, 3) == 0) {
        printf("最初の3文字は等しいです。\n");
    } else {
        printf("最初の3文字は等しくないです。\n");
    }
    return 0;
}

この例では、strncmp関数を使用して、str1str2の最初の3文字を比較しています。

複数の文字列をソートする

複数の文字列をソートするには、qsort関数を使用することができます。

qsort関数は、配列をソートするための汎用的な関数で、文字列の配列をソートする際にも利用できます。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compareStrings(const void *a, const void *b) {
    return strcmp(*(const char **)a, *(const char **)b);
}
int main() {
    const char *fruits[] = {"banana", "apple", "orange", "grape"};
    size_t numFruits = sizeof(fruits) / sizeof(fruits[0]);
    qsort(fruits, numFruits, sizeof(const char *), compareStrings);
    printf("ソートされた文字列:\n");
    for (size_t i = 0; i < numFruits; i++) {
        printf("%s\n", fruits[i]);
    }
    return 0;
}

この例では、qsort関数を使用して、fruits配列内の文字列を辞書順にソートしています。

compareStrings関数は、strcmpを利用して文字列を比較するためのコールバック関数です。

ソート後、文字列はアルファベット順に出力されます。

よくある質問

strcmp関数以外に文字列を比較する方法はある?

はい、strcmp関数以外にも文字列を比較する方法があります。

例えば、strncmp関数を使用して、指定した長さまでの部分文字列を比較することができます。

また、POSIX環境ではstrcasecmp関数を使用して、大文字小文字を無視した比較を行うことも可能です。

これらの関数は、特定の条件下での文字列比較に便利です。

なぜ==演算子で文字列を比較できないの?

==演算子は、ポインタのアドレスを比較するために使用されます。

文字列は配列として扱われるため、==演算子を使用すると、文字列の内容ではなく、文字列が格納されているメモリのアドレスを比較することになります。

そのため、文字列の内容を比較するためには、strcmp関数などを使用する必要があります。

例:if (strcmp(str1, str2) == 0)

strcmp関数はどのヘッダファイルに含まれている?

strcmp関数は、標準Cライブラリの<string.h>ヘッダファイルに含まれています。

このヘッダファイルをインクルードすることで、strcmp関数を使用することができます。

<string.h>には、他にも文字列操作に関する多くの関数が定義されています。

まとめ

この記事では、C言語における文字列比較の基本から応用までを詳しく解説しました。

strcmp関数の使い方や注意点を理解することで、文字列の比較を正確に行うことができるようになります。

これを機に、実際のプログラムで文字列比較を試してみて、さらにスキルを向上させてください。

  • URLをコピーしました!
目次から探す