C LANGUAGE TECHNOLOGY

【C言語】strcmp/strncmp関数と自作関数で文字列の比較

悩んでいる人

C言語のstrcmp/strncmp関数と自作関数で文字列を比較する方法を教えて!

こういった悩みにお答えします.

本記事の信頼性

  • リアルタイムシステムの研究歴12年.
  • 東大教員の時に,英語でOSの授業.
  • 2012年9月~2013年8月にアメリカのノースカロライナ大学チャペルヒル校コンピュータサイエンス学部2021年の世界大学学術ランキングで20位)で客員研究員として勤務.C言語でリアルタイムLinuxの研究開発
  • プログラミング歴15年以上,習得している言語: C/C++,Java,Python,Ruby,HTML/CSS/JS/PHP,MATLAB,Assembler (x64,ARM).
  • 東大教員の時に,C++言語で開発した「LLVMコンパイラの拡張」,C言語で開発した独自のリアルタイムOS「Mcube Kernel」GitHubにオープンソースとして公開

こういった私から学べます.

C言語で文字列の比較

C言語で文字列を比較する時は,Java言語やPython言語のように==演算子を使えません.

どうすればよいのかというと,標準ライブラリstring.hファイル内でプロトタイプ宣言されているstrcmp/strncmp関数を使います.

本記事では,strcmp/strncmp関数を含む以下の関数を紹介しますので,各々の関数の違いを学びましょう.

  • strcmp/strncmp関数
  • memcmp関数
  • strcasecmp/strncasecmp関数

strcmp/strncmp関数

strcmp/strncmp関数は,2つの文字列を比較します.

strcmp関数は,文字列s1と文字列s2を1文字ずつASCIIコードの値で比較します.

strcmp関数の戻り値は以下になります.

  • 正の値:s1がs2より大きい場合
  • 0:s1とs2が等しい場合
  • 負の値:s1がs2より小さい場合

strncmp関数は,s1とs2の最初のnバイトを比較する以外は,strcmp関数と同様です.

strcmp/strncmp関数の利用例

strcmp/strncmp関数の利用例を紹介します.

以下のコードは,10~13行目に定義した文字列をstrcmp/strncmp関数で比較します.

実行結果は以下になります.

処理系によってstrcmp/strncmp関数の戻り値は異なる場合がありますが,正負かどうかは同じになります.

strcmp/strncmp関数の注意点

strcmp/strncmp関数の利用の注意点を説明します.

以下の2つの文字列を比較する場合,異なる文字列であることはあなたは明らかですが,strcmp/strncmp関数を利用するとどうなるか確認してみましょう.

  • "abc\0d"
  • "abc\0ef"

以下のコードで,文字列"abc\0d"と"abc\0ef"をstrcmp/strncmp関数で比較します.

実行結果は以下になります.

strcmp/strncmp関数の戻り値が全て0なので,同じ文字列と判定しました.

この理由は,C言語では文字列の最後は'\0'文字(NULL文字,char型の1バイトの0)で終わるというルールがあるからです.

C言語の文字列のルールでは,"abc\0d"と"abc\0ef"は両方とも同じ文字列"abc"と認識することに注意して下さい.

また,printf関数の文字列のフォーマット指定子%sでは,両方とも"abc"を出力します.

strcmp/strncmp関数の自作

strcmp/strncmp関数を自作したmystrcmp/mystrncmp関数は,以下のコードになります.

実行すると,mystrcmp/mystrncmp関数はstrcmp/strncmp関数と同じ結果になることがわかります.

memcmp関数

memcmp関数はメモリ領域 s1とs2の最初のnバイトを比較します(各々のbyteはunsigned charとして解釈).

memcmp関数の戻り値は以下になります.

  • 正の値:s1がs2より大きい場合
  • 0:s1とs2が等しい場合
  • 負の値:s1がs2より小さい場合

memcmp関数は,strcmp/strncmp関数と異なり,"abc"と"abc\0de"を異なるデータとして認識します.

memcmp関数の利用例

memcmp関数の利用例とstrcmp/strncmp関数との違いを,以下のコードで説明します.

実行結果は以下になります.

7行目のmemcmp関数の戻り値が-1なので,異なるデータとして認識していることがわかります.

memcmp関数の自作

memcmp関数を自作したmymemcmp関数は,以下のコードになります.

実行結果は以下になります.

strcasecmp/strncasecmp関数

strcasecmp/strncasecmp関数は,2つの文字列s1とs2を大文字と小文字を区別せずに比較します.

strcasecmp/strncasecmp関数の戻り値は以下になります.

  • 正の値:s1がs2より大きい場合
  • 0:s1とs2が等しい場合
  • 負の値:s1がs2より小さい場合

strcasecmp/strncasecmp関数は,strcmp/strncmp関数とは異なり,"abc"と"ABC"を同じ文字列と認識します.

strcasecmp/strncasecmp関数の利用例

strcasecmp/strncasecmp関数の利用例は,strcmp/strncmp関数で紹介したコードstrcmp.cをベースに変更しています.

変更点は,以下になります.

  • 変数s3とs4に代入する文字列を,それぞれ大文字の文字列"AB"と"ABC"に変更(12~13行目)
  • strcasecmp/strncasecmp関数の呼び出し(27~41行目)

また,違いを比較するため,strcmp/strncmp関数の呼び出し(15~25行目)を残しています.

実行結果は以下になります.

strcasecmp/strncasecmp関数は文字列を大文字と小文字を区別せずに比較できていることがわかります(15行目と22行目).

strcasecmp/strncasecmp関数の自作

strcasecmp/strncasecmp関数を自作したmystrcasecmp/mystrncasecmp関数は,以下のコードになります.

mystrcasecmp/mystrncasecmp関数(17~27行目,29~58行目)を実装するために,大文字を小文字に変換するmytolower関数を実装しています(8~15行目).

まとめ

C言語で文字列を比較するためには==演算子ではなく,strcmp/strncmp関数を利用します.

また,memcmp関数やstrcasecmp/strncasecmp関数も有用であることがわかりました.

今回学んだ関数の比較は下表になります.

項目strcmp/strncmp関数memcmp関数strcasecmp/strcasecmp関数
比較対象文字列メモリデータ文字列
複数文字列の比較できないできるできない
大文字と小文字の区別ありありなし

C言語を独学で習得することは難しいです.

私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.

友だち追加

独学が難しいあなたは,C言語エンジニアになりたいあなたにおすすめのオンラインプログラミングスクール3社で自分に合うスクールを見つけましょう.

-C LANGUAGE, TECHNOLOGY
-, , , , , , , , ,

© 2021 元東大教員/アメリカのスタートアップCTO