■この記事の概要
この記事では、C言語のstrlen関数について、よくある誤解や誤用、関数の基本的な使い方を解説しています。
size_t型の戻り値やprintfでの書式指定、sizeofとの違い、文字列終端文字の重要性などを説明し、全角文字に関する注意点も触れています。
■strlen関数とは
strlen関数とはString lengthの略で、
文字列の長さを返す関数です。
筆者の回りでは「ストラレン」と
読む人が多いです。
■strlen関数とsizeof演算子の違い
#include <stdio.h>
#include <string.h>
int main(void){
char ary[1024] = "123";
char *ptr = "123";
puts("strlen");
printf("%zu\n",strlen("123")); //文字列の長さ
printf("%zu\n",strlen(ary)); //文字列の長さ
printf("%zu\n",strlen(ptr)); //文字列の長さ
puts("sizeof");
printf("%zu\n",sizeof("123")); //"123"+'\0'=4
printf("%zu\n",sizeof(ary)); //配列のサイズ
printf("%zu\n",sizeof(ptr)); //ポインタのサイズ
}
./a.out
strlen
3
3
3
sizeof
4
1024
8
strlen関数は文字列の長さを返します。
sizeof演算子の結果はオブジェクトを格納するのに必要なバイト数となります。
■strlen関数の戻り値は
intでもlongでもなくて、size_t型です。
参考
■strlen関数のprintf書式は%dではなくて%zu
#include <stdio.h>
#include <string.h>
int main(void){
puts("ダメ:移植性がない(コンパイラに警告されるかも)");
printf("%d\n", strlen("abc"));
printf("%ld\n", strlen("abc"));
printf("%x\n", strlen("abc"));
printf("%lx\n", strlen("abc"));
puts("良い:移植性がある");
printf("%zu\n", strlen("abc"));
printf("%zx\n", strlen("abc"));
}
C99より前の時代は
%dで良かったのですが、
C99以降は%zuを使わないと
コンパイラに警告されます。
■strlen関数は終端文字’\0’が無いと暴走する
#include <stdio.h>
#include <string.h>
int main(void){
//終端文字’\0’が無いと暴走する
char str0[4] = "abcd";
char str1[4] = "abcd";
char str2[4] = "abcd";
printf("%zu\n",strlen(str0));
printf("%zu\n",strlen(str1));
printf("%zu\n",strlen(str2));
puts("★");
char str3[] = "abcd";
char str4[] = "abcd";
char str5[] = "abcd";
printf("%zu\n",strlen(str3));
printf("%zu\n",strlen(str4));
printf("%zu\n",strlen(str5));
}
ご自分の環境でコンパイラを変えたり、
最適化レベルを変えてコンパイル実行してみてください。
実行結果が変わる(と思います)。
■strlen(“全角”)は4とは限らない
#include <stdio.h>
#include <string.h>
int main(void){
printf("%zu\n",strlen("全角"));
}
UTF8より前の時代は4と表示されたのですが、
今のUTF8の時代では6と表示されました。
■sizeof演算子は関数ではない
sizeof演算子を関数だと思っている人は結構多いです。
(参考YAHOO知恵袋の検索結果)
この人達は
【sizeofの戻り値】って書くのだけれど、
1+1の戻り値って言わないですよね。
聖典プログラミング言語C
A7.4.8 sizeof演算子では
【結果(result)】という表現を使ってます。
なので、
【sizeofの戻り値】ではなくて
【sizeofの結果】と書こう。
■sizeof演算子とstrlen関数の違い(配列の時)
#include <stdio.h>
#include <string.h>
int main(void)
{
char ary[1024] = "123";
printf("文字列の長さ = %zu\n",strlen(ary));
printf("配列のサイズ = %zu\n",sizeof(ary));
}
./a.out
文字列の長さ = 3
配列のサイズ = 1024
■sizeof演算子とstrlen関数の違い(ポインタの時)
#include <stdio.h>
#include <string.h>
int main(void)
{
char *ptr = "123";
printf("文字列の長さ = %zu\n", strlen(ptr));
printf("ポインタのサイズ = %zu\n", sizeof(ptr));
}
./a.out
文字列の長さ = 3
ポインタのサイズ = 8
参考: