どうも!初投稿になります!
ワイド社員のTHです。
社員の技術ブログ・・・、ということで今回は、
最近うっかりミスをしてしまったC言語のstrcmpとstrncmpの違いについて解説します。
strcmp関数について
まずは、strcmpから・・・。
strcmp(比較文字1(char型),比較文字2(char型))
①:比較文字1と比較文字2が同じであれば0を返す。
②:比較文字1>比較文字2なら正の値を返す。
③:比較文字1<比較文字2なら負の値を返す。
①はわかるけど・・・、②と③って数字でもないのに比較ってどういうこと?という疑問を抱く人がいるかもしれませんので一応解説しますと、
比較文字の先頭から一文字ずつ順番に比較していきます。
一文字ずつの大小については詳しく説明しませんが、簡単にいうと”ABC”と”ABD”を比較したときは、”ABD”が大きいという結果になり負の値を返します。
#include<stdio.h>; int mozicompare(char *mozi){ if (strcmp(mozi,"ABC") == 0 )return 1; if (strcmp(mozi,"ABCD") == 0 )return 2; if (strcmp(mozi,"AB") == 0 )return 3; return -1; }
というソースがあった場合、
moziに”ABC”を代入すると、1を返し、
moziに”ABCD”を代入すると、2を返し、
moziに”AB”を代入すると、3を返します。
strncmp関数について
では続いて、strncmpについてです。
ちなみに、私は関数名にnが入ってるだけですので、同じように使えるのでは?と初めて見たときに思いました。
strncmp(比較文字1(char型),比較文字2(char型),比較文字数(size_t型))
①:先頭から比較文字数分まで比較し、比較文字1と比較文字2が同じであれば0を返す。
②:先頭から比較文字数分まで比較し、比較文字1>比較文字2なら正の値を返す。
③:先頭から比較文字数分まで比較し、比較文字1<比較文字2なら不の値を返す。
関数にnが追加されると、指定した文字数までしか比較しない!
つまり、”ABC”と”ABD”を2文字まで比較した時、は①に当てはまるので0を返す!
#include<stdio.h>; int mozicompare(char *mozi){ if (strncmp(mozi,"ABC",3) == 0 )return 1; if (strncmp(mozi,"ABCD",4) == 0 )return 2; if (strncmp(mozi,"AB",2) == 0 )return 3; return -1; }
というソースがあった場合、
moziに”ABC”を代入すると、1を返し、
moziに”ABCD”を代入すると、1を返し、
moziに”AB”を代入すると、3を返します。
気づきました?strcmpと同じ文字を入れても違う結果になります。
実は、3文字しか比較していないため、4文字目以降は無意味なんです!
最後に
上記を踏まえて問題です。
下記2パターンのコードがあった場合、moziに下記のキーワードを代入した時、パターン1とパターン2で返す値が違うのはどれでしょう。
■リスト(moziの中身)
赤、黄、青、黄緑、緑青、緑
※緑青(読み方:ろくしょう)
//■パターン1 #include<stdio.h>; int mozicompare(char *mozi){ if (strcmp(mozi,"赤") == 0 )return 1; else if (strcmp(mozi,"黄") == 0 ) return 2; else if (strcmp(mozi,"青") == 0 ) return 3; else if (strcmp(mozi,"黄緑") == 0 ) return 4; else if (strcmp(mozi,"緑青") == 0 ) return 5; else if (strcmp(mozi,"緑") == 0 ) return 6; }
//■パターン2 #include<stdio.h>; int mozicompare(char *mozi){ if (strncmp(mozi,"赤",2) == 0 )return 1; else if (strncmp(mozi,"黄",2) == 0 ) return 2; else if (strncmp(mozi,"青",2) == 0 ) return 3; else if (strncmp(mozi,"黄緑",4) == 0 ) return 4; else if (strncmp(mozi,"緑青",4) == 0 ) return 5; else if (strncmp(mozi,"緑",2) == 0 ) return 6; }
答え
↓
↓
↓
↓
↓
↓
黄緑
理由:パターン1の場合、moziの中身全てを比較するため、パターン2の場合は、strncmpの第3引数の値までしか比較しないため、
黄緑のみ、パターン2の黄と1文字比較するときに、合致して返す値が2となります。よって違いがあるのは黄緑です。
こういった仕様について考えるのも、プログラムの楽しいところのひとつだと思います。