C言語でデータの比較をする際、よく使用するのがstrcmpとmemcmpです
どちらも同じような目的で使用されますが、このstrcmpとmemcmpの違いに着目しつつ、strcmpとmemcmpを使ったサンプルソースとともに説明します
目次
strcmpの構文
#include <string.h>
int strcmp(const char *s1, const char *s2);
strcmpの説明
strcmpは、s1で指定されたポインタから始まるNULL文字(’\0’)で終わる文字列と、s2でい指定されたポインタから始まるNULL文字(’\0’)で終わる文字列を比較します
strcmp関数は、s1が指す文字列とs2が指す文字列を比較する
JISX3010 プログラム言語C
比較元となるNULL文字(’\0’)で終わる文字列の先頭を指すポインタを指定します
比較先となるNULL文字(’\0’)で終わる文字列の先頭を指すポインタを指定します
s1 と s2で指定された文字列を比較した結果
s1 と s2で指定された文字列が一致する場合、0 を返します
s1 で指定された文字列が大きい場合、> 0 (正の値)を返します
s1 で指定された文字列が小さい場合、< 0 (負の値)を返します
memcmpの構文
#include <string.h>
int memcmp(const void *s1, const void *s2, size̲t n);
memcmpの説明
memcmpは、s1で指定されたポインタから始まる n バイトと、s2で指定されたポインタから始まる n バイトを比較します
memcmp関数は、s1が指すオブジェクトの始めのn文字と、s2が指すオブジェクトの始めのn文字を比較する
JISX3010 プログラム言語C
比較元となるバイトデータの先頭を指すポインタを指定指定します
比較先となるバイトデータの先頭を指すポインタを指定指定します
比較するバイト数を指定します
s1 と s2 で指定された n バイトのデータを比較した結果
s1 と s2 で指定されたバイトデータが一致する場合、0 を返します
s1 で指定された nバイトのデータが大きい場合、> 0 (正の値)を返します
s1 で指定された nバイトのデータが小さい場合、< 0 (負の値)を返します
strcmpとmemcmpの使い方サンプル
strcmpとmemcmpを使用するサンプルプログラムとその実行結果を、パターン別に紹介します
比較結果が一致する場合
#include <stdio.h>
#include <string.h>
/*
* strcmpとmemcmpのサンプル
*/
int main(int argc, char *argv[]) {
// 等しい結果となる場合のサンプル
char s1[256] = "abcdef12345";
char s2[256] = "abcdef12345";
size_t n = 256;
int ret1 = 0;
int ret2 = 0;
fprintf(stdout, "s1[%.256s], s2[%.256s], n[%d]\n", s1, s2, (int)n);
ret1 = strcmp(s1, s2);
ret2 = memcmp(s1, s2, n);
fprintf(stdout, "strcmp [%d], memcmp [%d]\n", ret1, ret2);
}

比較元が大きい場合
#include <stdio.h>
#include <string.h>
/*
* strcmpとmemcmpのサンプル
*/
int main(int argc, char *argv[]) {
// 比較元が大きい結果となる場合のサンプル
{
// 長さが同じ場合('f' > 'F')
char s1[256] = "abcdef12345";
char s2[256] = "abcdeF12345";
size_t n = 256;
int ret1 = 0;
int ret2 = 0;
fprintf(stdout, "s1[%.256s], s2[%.256s], n[%d]\n", s1, s2, (int)n);
ret1 = strcmp(s1, s2);
ret2 = memcmp(s1, s2, n);
fprintf(stdout, "strcmp [%d], memcmp [%d]\n", ret1, ret2);
}
{
// s1が長い場合
char s1[256] = "abcdef12345";
char s2[256] = "abcdef";
size_t n = 256;
int ret1 = 0;
int ret2 = 0;
fprintf(stdout, "s1[%.256s], s2[%.256s], n[%d]\n", s1, s2, (int)n);
ret1 = strcmp(s1, s2);
ret2 = memcmp(s1, s2, n);
fprintf(stdout, "strcmp [%d], memcmp [%d]\n", ret1, ret2);
}
{
// s2が長い場合('f' > 'F')
char s1[256] = "abcdef";
char s2[256] = "abcdeF12345";
size_t n = 256;
int ret1 = 0;
int ret2 = 0;
fprintf(stdout, "s1[%.256s], s2[%.256s], n[%d]\n", s1, s2, (int)n);
ret1 = strcmp(s1, s2);
ret2 = memcmp(s1, s2, n);
fprintf(stdout, "strcmp [%d], memcmp [%d]\n", ret1, ret2);
}
}

比較元が小さい場合
#include <stdio.h>
#include <string.h>
/*
* strcmpとmemcmpのサンプル
*/
int main(int argc, char *argv[]) {
// 比較元が小さい結果となる場合のサンプル
{
// 長さが同じ場合('f' > 'F')
char s1[256] = "abcdeF12345";
char s2[256] = "abcdef12345";
size_t n = 256;
int ret1 = 0;
int ret2 = 0;
fprintf(stdout, "s1[%.256s], s2[%.256s], n[%d]\n", s1, s2, (int)n);
ret1 = strcmp(s1, s2);
ret2 = memcmp(s1, s2, n);
fprintf(stdout, "strcmp [%d], memcmp [%d]\n", ret1, ret2);
}
{
// s1が長い場合('f' > 'F')
char s1[256] = "abcdeF12345";
char s2[256] = "abcdef";
size_t n = 256;
int ret1 = 0;
int ret2 = 0;
fprintf(stdout, "s1[%.256s], s2[%.256s], n[%d]\n", s1, s2, (int)n);
ret1 = strcmp(s1, s2);
ret2 = memcmp(s1, s2, n);
fprintf(stdout, "strcmp [%d], memcmp [%d]\n", ret1, ret2);
}
{
// s2が長い場合
char s1[256] = "abcdef";
char s2[256] = "abcdef12345";
size_t n = 256;
int ret1 = 0;
int ret2 = 0;
fprintf(stdout, "s1[%.256s], s2[%.256s], n[%d]\n", s1, s2, (int)n);
ret1 = strcmp(s1, s2);
ret2 = memcmp(s1, s2, n);
fprintf(stdout, "strcmp [%d], memcmp [%d]\n", ret1, ret2);
}
}

strcmpとmemcmpの使い方まとめ
strcmp は、文字列として比較するので、データの最後にNULL文字(’\0’)が必要
memcmpは、サイズを指定して比較するので、データの最後にNULL文字(’\0’)は必要ない
strcmpを使用する際の注意点は、データの最後にNULL文字(’\0’)が必要なので、NULL文字(’\0’)が存在しないデータを指定した場合は、アクセス可能領域外へのアクセスが発生してしまうので注意が必要です
strcmpでは、NULL文字(’\0’)をデータの終端として扱うので、NULL文字(’\0’)を途中に含むデータを比較することはできません
memcmpを使用する際の注意点は、正しいサイズを指定しないと正しい結果が得られない事です(データの長さが違う場合は、長い方を指定する)
特に、比較するデータの長さが違う場合、長い方のサイズで比較しないと途中まで一緒の場合などがあるため正しい結果は得られません
また、sizeof 演算子を使用した場合に、使用方を間違えると正しいサイズが取得できないので注意が必要です
データの比較をしたい場合、大部分はデータサイズが同じもの同士の比較になるため、memcmp で比較するようにした方がコードも統一されて見やすくなります