文字列の長さの取得

文字列操作1

C言語では、文字列はchar型の配列に代入して扱うことができます。
(→文字型と文字列)
ポインタで扱うという方法もありますが、これは別途説明します。

配列で扱う都合上、簡単な処理であってもやや複雑なコードを書かなければなりません。
文字列処理のために毎回コードを書いていては面倒なので、誰もがよく行うであろう処理はC言語の標準ライブラリ関数として提供されています。
自分で処理を書くよりも簡単で、バグの心配もないので特別な理由がなければ標準関数を使いましょう。

strlen関数

文字列の長さを取得するにはstrlen関数を使用します。

#include <stdio.h>
#include <string.h>

int main()
{
    char str[100] = "ABCDE";

    printf("%d", strlen(str));

    getchar();
}
5

文字列操作関数を使用するにはコードの先頭に「#include <string.h>」の記述が必要です。

size_t strlen(
 const char *str
);
文字列strの先頭からNULL文字が出現するまでのバイト数を取得する。

引数には長さを取得したい文字列配列を指定します。

strlen関数の戻り値は終端のNULL文字までの文字数です。
char型は1バイトの情報量なので、つまりバイト数と同じです。
ただしNULL文字は除外された値です。
上のコードでは「ABCDE」とNULL文字で文字列全体で必要なバイト数は「6」ですが、strlen関数の実行結果は「5」となります。

名前が似ている関数たち

C言語の標準ライブラリには、同じような機能を提供する、同じような名前の関数が複数存在することがあります。
strlen関数も、strnlen、strnlen_s等が存在します。
さらに、wcsnlen_s、_mbsnlenなどもあります。
(本当はもっとあります)

「str」というのは文字列を意味する「string」の省略形です。
文字列操作関数名には大抵「str」が付けられています。

str「n」系

strnlen関数はより安全なstrlen関数です。
strlenとstrnlenの違いは、第一引数の文字列の長さを指定する引数が増えていることです。
(nはおそらくnumberかnumericの意味)

size_t strnlen(
 const char *str
 size_t numberOfElements
);
文字列strの先頭からNULL文字が出現するまでのバイト数を取得する。
ただしnumberOfElements以上のデータは読み取らない。

strlen関数はNULL文字が出現するまで文字を読み込みます。
もしstrlen関数にNULL文字で終わらないchar配列を指定すると、配列のメモリ領域を超えてデータを読み込み続けてしまいます。
これを防ぐために、strnlen関数では第二引数で指定した文字数以上は読み込まないように最大値を指定できるようになっています。
第二引数以上の文字数を持つchar型配列を第一引数に指定すると、第二引数の値が返ります。

最初のサンプルコードのように、NULL文字で終わることが確実な場合はstrlen関数でかまいませんが、できるだけ安全な関数を使用するクセを付けたほうが良いでしょう。

#include <stdio.h>
#include <string.h>

int main()
{
    char str[100] = "ABCDEFGHIJ";
    printf("%d", strnlen(str, 6));
    getchar();
}

このコードの配列strの中の文字列の長さは本来は「10」ですが、strnlen関数で最大値を「6」に制限しているため「6」を返します。

語尾に「_s」系

strnlen_s関数はセキュリティの強化版です。
(語尾の「_s」はセキュリティ、セキュアのsです)

size_t strnlen_s(
 const char *str
 size_t numberOfElements
);
文字列の長さを取得する

使い方はstrnlen関数と同じです。
strnlen関数は第一引数に不正な値(NULL)を指定するとエラーが発生し、プログラムが停止してしまいます。
strnlen_s関数の場合は0を返し、プログラムは停止しません。

頭に「_m」、「w」系

これらは日本語などの1バイトでは表せない文字(マルチバイト文字、ワイド文字)を扱うための関数です。

C言語では日本語ひとつを表すのに2バイト以上を必要とします。
つまり「あ」という一文字を扱う場合でもchar型の要素数2以上の配列が必要ということです。
(プラスNULL文字の分の容量も必要です)
これをマルチバイト文字といいます。

strlen関数は日本語などの文字は想定しておらず、正確な文字数を得ることができません。
日本語を含む文字列の文字数を正確にカウントするには「_mbstrlen関数」を使用します。
#include <locale.h>」と「#include <stdlib.h>」の二つが先頭に追加されていることに注意してください。

#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <stdlib.h>

int main()
{
	char str[100] = "あいうえおABC";

	printf("%d\n", strlen(str));

	setlocale(LC_ALL, "");

	printf("%d", _mbstrlen(str));

	getchar();
}
13
8
size_t _mbstrlen(
 const char *str
);
文字列の長さを取得する(マルチバイト版)

11行目のstrlen関数では日本語を2文字とカウントしてしまい、正しい文字数は取得できません。
16行目の_mbstrlen関数では日本語も1文字とカウントし、正しい文字数(8文字)を表示できます。

_mbstrlen関数で正しい文字数を取得するには、その前にsetlocale関数を実行する必要があります。
この関数は、マルチバイト系の関数で使用する「地域、言語」の設定(ロケール)を行います。
詳細な使い方は省略しますが、マルチバイト文字系の関数を使用する前にサンプルコードのように一度だけ呼び出しておく、と覚えておけば問題ありません。

実は_mbstrlen関数はVisualStudioでしか使用できない、マイクロソフトの独自の関数です。
他のコンパイラでは使用できません。

また、上記コードのstrlen関数の実行結果は「13」となっていますが、これもコンパイラによって異なります。

これらはやや複雑な話となります。
詳しくは文字コードマルチバイト文字の項を参照してください。