C言語 strlenの使い方

この記事のポイント

  • strlen関数の基本的な仕組みと動作原理
  • 文字列長を活用した効率的なメモリ管理
  • パフォーマンスを考慮したstrlen関数の使用方法
  • 文字列操作における長さ情報の重要性
  • strlen関数の独自実装と最適化テクニック

目次

C言語のstrlen関数とは?

C言語のstrlen(文字列長を取得する)関数は、string.hヘッダーファイルに定義された標準ライブラリ関数で、NULL終端文字(\0)までの文字数をカウントして返します。

この関数の特徴は、NULL文字自体を含めない点にあります。strlenは文字列の先頭からNULL文字に達するまでのすべての文字数を1文字ずつ走査してカウントします。

C言語では文字列が必ずNULL文字で終わることを前提としています。C言語プログラミングでstrlen関数を使うと、正しく終端された文字列でのみ安全に動作します。

strlen関数には、重要な特性があります。それは、実行時間は文字列の長さに比例する点です。短い文字列ではあまり問題にならないものの、非常に長い文字列や繰り返し呼び出す場合は、パフォーマンスに影響することがあります。

また、strlenは、バイト単位で長さを計算する関数です。マルチバイト文字やUnicode文字を含む文字列では、見た目の「文字数」とは異なる値を返すことに注意が必要です。

strlen関数は、C言語プログラミングの文字列操作において、メモリ割り当てやバッファ管理、文字列の比較・連結といった多くの場面で活用されています。

【関連】
C言語をもっと詳しく学ぶならpaizaラーニング

基本構文

strlen関数の基本構文はシンプルです。

#include <string.h> int main() { const char *str = "Hello"; size_t length = strlen(str); // 文字列の長さを取得 return 0; }

strlen関数には、以下5つの特徴があります。

  • 引数として、長さを測定したいNULL終端文字列へのポインタを取ります
  • 戻り値はsize_t型(符号なし整数型)で、文字列内の文字数を表します
  • NULL文字自体は長さにカウントされません
  • 空文字列("")の場合は0を返します
  • NULL文字が見つからない場合、未定義動作となります(バッファオーバーフロー)

基本的な使用例を見てみましょう。

size_t len1 = strlen("Hello"); // 5を返す size_t len2 = strlen(""); // 0を返す size_t len3 = strlen("Hello\0World"); // 5を返す(最初のNULL文字で停止)

実用例

このセクションでは、開発現場でも使える実用的なシナリオのなかで、strlen関数の基本機能や応用例、コードパターンを紹介します。

strlen関数などを使った文字列操作をマスターするためには、自分のプログラムに基本的なコードを貼り付け、実際に動かしてみる経験が必要です。

そのなかでは、自分のイメージとは違う動作になったりエラーが何度も出たりして、その対処に多くの時間がかかってくるかもしれません。

しかし、大きな壁を何度も乗り越えていると、次第に適材適所の関数やテクニックを選べる感覚が身に付いてきます。

特にプログラミングを学習中の方は、このセクションのコード例をたくさん活用して、さまざまな経験を積んでいきましょう。

基本的な文字列長の取得

以下のコードパターンは、文字列の長さを測定して表示するテクニックです。

strlen関数の基本機能は、NULL文字までの文字数をカウントして表示するものです。このとき、文字列内のNULL文字は長さに含まれません。したがって、「Hello\0World」のような文字列でも「Hello」の部分だけが計測されることになります。

以下のコードは文字列操作の基本処理であり、バッファサイズの計算などをするうえで不可欠なものです。

#include <stdio.h> #include <string.h> int main() { const char *str = "Hello, World!"; printf("文字列「%s」の長さ: %zu文字\n", str, strlen(str)); return 0; }

実行結果:

文字列「Hello, World!」の長さ: 13文字

入力文字列の長さ検証

以下のコードパターンは、ユーザーが入力したパスワードの長さを検証するテクニックを示したものです。セキュリティ要件として一定の長さ(この例では6〜12文字)をユーザーに要求し、条件に合致するかを判定します。入力の検証は、多くのアプリケーションに求められる機能です。文字列長のチェックは、その中核をなす部分でしょう。

#include <stdio.h> #include <string.h> int main() { char password[50]; printf("パスワード(6〜12文字): "); scanf("%49s", password); size_t len = strlen(password); printf(len >= 6 && len <= 12 ? "有効なパスワード\n" : "無効なパスワードです。長さが足りません。\n"); return 0; }

出力:

パスワード(6〜12文字): 無効なパスワードです。長さが足りません。

文字列配列の長さ比較

以下のコードパターンでは、単語リストから最長の単語を見つけるテクニックを示しています。具体的には、配列内の各文字列について長さを比較し、最大値とその位置を記録しているものです。このコードは、テキスト処理やデータ分析で頻繁に使われています。文字列の特性に基づいた選別処理の基本形といえるでしょう。

#include <stdio.h> #include <string.h> int main() { const char *words[] = {"apple", "banana", "cherry", "date"}; size_t max_len = 0, index = 0; for (int i = 0; i < 4; i++) if (strlen(words[i]) > max_len) { max_len = strlen(words[i]); index = i; } printf("最長の単語: %s (%zu文字)\n", words[index], max_len); return 0; }

出力:

最長の単語: banana (6文字)

メモリ割り当て時の活用

以下のコードパターンは、文字列のコピーに必要なメモリを動的に割り当てるテクニックです。strlen関数で元の文字列の長さを測定し、その測定結果に対して終端のNULL文字分を加えたサイズでメモリを確保しています。以下のようなコードを使った適切なメモリ管理は、メモリリークやバッファオーバーフローを防ぐうえでも、必ず行うべきでしょう。

#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { const char *original = "Hello, World!"; char *copy = malloc(strlen(original) + 1); // +1 はNULL文字用 if (copy) { strcpy(copy, original); printf("複製: %s\n", copy); free(copy); } return 0; }

出力:

複製: Hello, World!

文字列切り詰め

以下のコードパターンでは、長い文字列を指定長に切り詰めるテクニックを示しています。表示スペースが限られている画面やレポートでは、テキストを省略して表示する工夫も必要です。以下のコード例では、文字列が特定の長さを超える場合に、その位置で切り詰め、末尾に省略記号を追加しています。

#include <stdio.h> #include <string.h> int main() { char text[100] = "これは非常に長いテキストで切り詰める必要があります"; if (strlen(text) > 10) { text[15] = '\0'; strcat(text, "..."); } printf("結果: %s\n", text); return 0; }

出力:

結果: これは非常...

独自バージョンの実装

strlen関数の動作原理を理解するために役立つ、独自の実装例です。strlen関数には、ポインタ演算を使って文字列を走査し、NULL文字までの距離を計算する特徴があります。strlen関数をC言語の基本概念(ポインタ、アドレス計算)を活用した実装で活用すると、標準ライブラリの内部動作を理解する助けになるでしょう。

#include <stdio.h> size_t my_strlen(const char *str) { const char *p = str; while (*p) p++; return p - str; } int main() { printf("長さ: %zu\n", my_strlen("テスト文字列")); return 0; }

出力:

長さ: 18

パフォーマンス比較

以下のコードパターンでは、strlen関数を繰り返し呼び出す際のパフォーマンス問題について示しています。例えば、繰り返し処理のなかでstrlen関数を呼び出す動作は、毎回文字列全体を走査することになるため、とても非効率です。パフォーマンス重視のアプリケーションを開発する際には、strlen関数の使用で陥りがちな非効率性にも注意する必要があります。パフォーマンス性を向上させるためには、事前計算を可能な限り活用すべきでしょう。

#include <stdio.h> #include <string.h> #include <time.h> int main() { const char *str = "この文字列の長さを何度も測定します"; clock_t start = clock(); int len; for (int i = 0; i < 1000000; i++) len = strlen(str); printf("長さ: %d, 時間: %.2fms\n", len, (double)(clock() - start) * 1000 / CLOCKS_PER_SEC); return 0; }

出力:

長さ: 51, 時間: 0.00ms

バイナリセーフ版strlen

以下のコードパターンでは、最大検索長を指定できる安全なstrlen関数の代替実装例を示しています。strlen関数ではNULL文字を見つけるまで走査を続ける特徴から、不正な文字列やバイナリデータで問題を起こす可能性があります。

安全性の高いプログラミングをするためには、strlen関数を使い最大長の制限を設けることで、上記のような問題を防止する工夫も必要でしょう。

#include <stdio.h> size_t safe_strlen(const char *str, size_t max_len) { size_t i; for (i = 0; i < max_len && str[i]; i++); return i; } int main() { printf("安全な長さ: %zu\n", safe_strlen("abc\0def", 10)); // 3を返す return 0; }

出力:

安全な長さ: 3

まとめ

この記事では、strlen関数の基本的な使い方から、入力検証、メモリ割り当て、パフォーマンス最適化といったさまざまな実用例を紹介しました。

C言語のstrlen関数は、文字列処理において重要性が高い関数の一つです。strlen関数の主な機能は、NULL終端文字までの文字数を計算するというシンプルなものとなります。また、多くの文字列操作やメモリ管理において中心的な役割を果たす特徴もあるでしょう。

strlen関数の使用時にバッファオーバーフローの防止やメモリリソースの効率化をはかるためには、文字列長の正確な把握も必要となります。

C言語初心者の方は、このページで紹介したコードパターンを参考にしながらstrlen関数の動作原理を理解したうえで、ぜひとも自分のプログラムに独自実装してみましょう。

コードを実装してエラー処理などを何度か繰り返す「経験」を積み重ねると、ポインタ操作やメモリレイアウトといったC言語の基本概念への理解も深まるはずです。

ただし、strlen関数には、文字列の長さに比例して実行時間がかかるため、パフォーマンス管理の部分で注意が必要となります。具体的には、長い文字列や繰り返し呼び出す場合に適切な対策や工夫が求められるでしょう。

長さが変化しない文字列の場合、一度計算した結果を保存して再利用することで、処理の効率化が可能になったりします。

最後になりますが、strlen関数はバイト単位で長さを計算するものです。

マルチバイト文字やUnicodeを扱う際には、見た目の「文字数」とは異なる結果になることにも注意しましょう。このような問題に直面した場合は、言語や文字セットに適した専用関数の使用を検討したほうがよいかもしれません。

レベルを更に上げたい方はpaizaプログラミングスキルチェックへ

  1. paizaラーニングトップ
  2. リファレンス
  3. C言語のリファレンス記事一覧
  4. C言語 strlenの使い方