C LANGUAGE TECHNOLOGY

【C言語】strlen関数と自作関数で文字列の長さの計算

悩んでいる人

C言語のstrlen関数と自作関数で文字列の長さの計算方法を教えて!

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

本記事の信頼性

  • リアルタイムシステムの研究歴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言語のstrlen関数で文字列の長さを計算する方法を紹介します.

また,strlen関数を拡張したstrnlen関数とstrnlen_s関数も紹介します.

strlen関数

strlen関数は,sが指す文字列の長さを計算します.

strlen関数はANSI C規格で定義されています.

また,NULL文字('\0')は計算に含まれません.

strlen関数の利用例

strlen関数の利用例は,以下のコードになります.

実行結果は以下になります.文字列"abc"の長さが3と出力されていることがわかります.

strlen関数とsizeof演算子の違い

strlen関数とsizeof演算子の違いを以下のコードで解説します.

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

sizeof演算子の結果は,配列の場合は配列のサイズ(この例ではBUFSIZEの16バイト),ポインタの場合はchar *型のサイズ(私の環境では8バイト)になることに注意して下さい.

strlen関数の自作

strlen関数の自作関数は以下のコードになります.

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

文字列"abc"の長さを3と計算できていることがわかります.

strlen関数の問題点

strlen関数は,NULL文字を発見するまで読み込んでしまいます.

もし確保したメモリ領域の中にNULL文字がない場合,バッファオーバーリードが発生して,その外側のメモリ領域まで読み込んでしまいます.

バッファオーバーリードのコードは以下になります.

私の環境での実行結果は以下になります.

配列s1のサイズが16なのに対して,文字列の長さが22になっています.

また,初期化していないs2の文字列の長さが11になり,文字化けが発生しています.

strnlen関数

strnlen関数では,strlen関数で発生するバッファオーバーリードの問題を回避できます.

具体的には,strnlen関数は第2引数のmaxlenに読み込む上限を設定できます.

ここで,strnlen関数はC言語の標準ではなく,POSIX.1-2008規格です.

なので,処理系によってはstrnlen関数が存在しない場合があることに注意して下さい.

strnlen関数の利用例

strnlen関数の利用例は以下のコードになります.

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

strnlen関数の戻り値が第2引数で指定した読み込む上限以下になっていることがわかります.

strnlen関数の自作

strnlen関数の自作は以下のコードになります.

自作したmystrlen関数とstrlen関数の違いは,maxlenを超えない範囲でwhileループを実行して配列の要素を読み込むことです.

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

strnlen_s関数

strnlen_s関数は,strnlen関数と同じくバッファオーバーリードを回避する関数です.

strnlen_s関数は,C11規格のオプションです.

GCC/Clangでは実行できませんが,Visual Studioで実行できます.

第1引数にNULLを指定するとstrnlen_s関数は0を返しますが,strlen関数とstrnlen関数はセグメンテーション違反が発生します.

ただし,strnlen関数の第2引数が0の場合は0を返すことに注意して下さい.

strnlen_s関数の利用例

strnlen_s関数の利用例は以下になります.

Windows 10のVisual Studioでの実行結果は以下になります.

strnlen_s関数の自作

strnlen_s関数の自作は以下のコードになります.

mystrnlen関数とは異なり,mystrnlen_s関数は第1引数がNULLかどうか判定します(14~16行目).

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

※自作関数なので,GCC/Clangで実行できます.

まとめ

C言語のstrlen関数で文字列の長さを計算する方法を紹介しました.

また,strlen関数のバッファオーバーリードを回避するstrnlen関数とstrnlen_s関数も紹介しました.

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

項目strlen関数strnlen関数strnlen_s関数
規格ANSI CPOSIX.1-2008C11
実行可能な開発環境GCC/Clang/Visual StudioGCC/Clang/Visual StudioVisual Studio
バッファオーバーリードの回避できないできるできる
第1引数にNULLセグメンテーション違反第2引数が0の場合は0を返す.
第2引数が1以上の場合は
セグメンテーション違反.
0を返す

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

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

友だち追加

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

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