文字列を空にする | Programming Place Plus C言語編 逆引き

トップページC言語編逆引き

このページの概要

以下は目次です。

目的

文字の配列があるとき、それを空の状態にしたいとします。

空の状態とは、文字列の長さが 0 の状態です。


C言語の文字列は、文字の配列です。C言語の配列は、1度決めた要素数を変えることができませんから、配列そのものを縮めるという方向性では不可能です。

C言語の文字列には、末尾にヌル文字(‘\0’)が付加されるルールがあります(第8章)。これを利用して、0文字目にいきなり ‘\0’ が登場するようにすれば、実質的にその文字列は空であるといえます。たとえば、strlen関数に渡すと 0 が返ってきます。

このページでは、これを実現する方法を2つ取り上げます。いずれの方法もよく使われており、効率面と安全性で、多少議論が起こる話ではあります(参考リンク1)。


ちなみに、次のようなコードはコンパイルできません。

int main(void)
{
    char s[] = "abcde";
    s = "";  // コンパイルエラー
}

文字列は配列なので、"" も配列です(char[1])。そして、配列は代入できず、ポインタに置き換えられてしまいます(第32章)。

方法①(先頭の文字をヌル文字にする)

冒頭の説明そのままですが、文字列の最初の文字をヌル文字(‘\0’)にするだけです。

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

int main(void)
{
    char s[] = "abcde";

    s[0] = '\0';

    puts(s);
    printf("%zu\n", strlen(s));

    printf("%c%c%c%c%c\n", s[0], s[1], s[2], s[3], s[4]);
    printf("%zu\n", sizeof(s));
}

実行結果:


0
 bcde
6

s[0] = '\0'; のように、文字の配列の 0番目の要素にヌル文字を代入するだけです。

実行結果をみると、puts関数の出力が改行だけになっており、strlen関数が返す結果も 0 になっています。

一方で、当然ながら s[1]~s[4] には文字が入ったままであることは、理解しておかなければなりません。また、sizeof演算子で配列全体の大きさを調べた場合も当然、元の大きさのままです。


たった1文字の代入だけで、文字列を空にしたことにできるので、この方法は非常に効率的です。

しかし、「文字列を空にした」=「文字列をクリアした」と思いたいのならば、この方法には不満があるかもしれません。うっかり s[1]~s[4] のどこかを参照すると、クリアしたはずの文字があるわけですから。これが問題であれば、方法② を使います。


なお、strcpy関数を使って、次のように書くことはできますが、わざわざ、関数呼び出しのコストを払う意味はありませんから、避けたほうがいいです。

strcpy(s, "");

方法②(配列全体をヌル文字でクリアする)

先頭の文字だけでなく、配列の全要素をヌル文字にしてしまう方法です。

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

int main(void)
{
    char s[] = "abcde";

    memset(s, '\0', sizeof(s));

    puts(s);
    printf("%zu\n", strlen(s));

    printf("%c%c%c%c%c\n", s[0], s[1], s[2], s[3], s[4]);
    printf("%zu\n", sizeof(s));
}

実行結果:


0

6

配列全体にヌル文字を入れるには、memset関数を使うのが簡単です。

実行結果のように、中身の文字は完全になくなっています。

sizeof演算子が返す結果は、配列の大きさは変わらないので、元のままです。


文字列が全体的にクリアされるため、方法① のように、消したつもりでいた文字が残ったままになる不満点は解消されます。しかし、方法① なら1文字だけ代入すれば済むので、効率が落ちます。


参考リンク

  1. C言語での文字列の初期化はどうしていますか? | teratail
    • 方法①、方法② のそれぞれ取り上げられており、現場経験などを踏まえた回答が付いている


更新履歴



逆引きのトップページへ

C言語編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る