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);
この関数は、str1
とstr2
を比較し、その結果を整数値で返します。
strcmp関数の返り値の意味
strcmp関数
の返り値は、以下のように解釈されます。
返り値 | 意味 |
---|---|
0 | str1 とstr2 が等しい |
負の値 | str1 がstr2 より辞書順で前にある |
正の値 | str1 がstr2 より辞書順で後にある |
この返り値を利用して、文字列の比較結果を判断することができます。
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;
}
この例では、str1
とstr2
をstrcmp関数
で比較し、その結果に応じて異なるメッセージを出力します。
str1
がstr2
より辞書順で前にある場合、"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関数
を使用して、str1
とstr2
の最初の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
を利用して文字列を比較するためのコールバック関数です。
ソート後、文字列はアルファベット順に出力されます。
よくある質問
まとめ
この記事では、C言語における文字列比較の基本から応用までを詳しく解説しました。
strcmp関数
の使い方や注意点を理解することで、文字列の比較を正確に行うことができるようになります。
これを機に、実際のプログラムで文字列比較を試してみて、さらにスキルを向上させてください。