C
1 char str[31+1]; 2 //配列の先頭をヌル終端すればそれで良い? 3 str[0] = '\0'; 4 //それとも要素すべてにヌル終端する? 5 memset(str, '\0', sizeof(str));
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
![guest](/img/icon/icnUserSample.jpg)
回答8件
0
私は、結論としては、str[0] = '\0';という書き方を薦めます。
まず、静的配列の初期化について。
現在のC言語ではchar str[31+1] = {};という書き方が認められていますが、古いバージョンのCでは、この書き方は認められておらず、{0}としなければなりません。
また、当たり前ですがこの方法は、静的配列でなければ使えません。
次に、memsetを使用する方法。これはどのバージョンのCでも使えますし、すべての要素を確実に0にすることができます。しかしこれにはオーバーヘッドの問題があります。memsetを使うということは、コンパイラがもっと高速な方法を知っていたとしてもそれを使わないと明示してしまうことなのです。
(ほかにも、ゼロクリアと初期化は本質的には違うという問題がありますが、C++プログラマでなければあまり重要ではないかもしれません。)
ではどうすればいいのか。
そこで提案するのが、先頭文字をヌル文字で上書きするという方法です。
ご存じのとおり、こうすればstrは空文字列として扱われます。
静的配列の初期化以外の場面でも使える、万能な方法です。
「この配列がどのように使われるかわからないではないか」という批判は、間違ってはいません。
しかし、strという名前を付けている以上、これは文字列として扱うことが明らかです。
プログラマはユーザーではありません。自分のコードに手を加える人間を全く信用せず、予防的にゼロクリアをするのは、過剰な行動だといえます。ライブラリの都合で、ゼロクリアする必要があるなら、そのときはコメントで補足したうえでゼロクリアすればいいのです。
以下、参考にしたURLです。
http://cpplover.blogspot.jp/2010/09/blog-post_18.html
投稿2015/12/17 06:13
総合スコア1722
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
![退会済みユーザー](https://ddjkaamml8q8x.cloudfront.net/profileImages/deletedUser/icnUserSample.jpeg)
退会済みユーザー
2015/12/17 09:30 編集
2015/12/18 02:58
2015/12/18 06:14 編集
2019/08/01 09:48
![guest](/img/icon/icnUserSample.jpg)
0
「文字列の初期化」という言葉が曖昧だと思います。
「文字列を空文字列にする」だと、str[0] = '\0';
だし、
「文字列のエリアをオールゼロにする」だと、memset(str, '\0', sizeof(str));
だし。
「文字列を空白(あるいは数字のゼロ)で埋める」だと、また違うことをしないといけないし。
何をしたいのかによって、適切な手段があるかと思います。
「初期化」というと、変数宣言時に値を与えることに限定して捉える人が少なからずだと思いますよ。
それが正しいとは思いませんが。
投稿2015/12/17 06:24
総合スコア85458
0
C
1 // コードの意図が: 2 // strを文字列として扱うなら 3 str[0] = '\0'; 4 // char配列として扱うなら 5 memset(str, '\0', sizeof(str));
投稿2019/08/01 10:08
総合スコア16614
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
既に他の回答者の皆様が回答されているとおりですが、
以下、経験上のお話をさせてください。
str[0] = '\0'
は、str[0]
に直接何か文字をセットしてしまうとNULL終端を失うことになり、バグの原因になりがちです。
memset(str, '\0', sizeof(str))
は、ものすごく巨大な文字列だと全てを初期化することになるので、場合によってはパフォーマンスの問題になります。
レベルがまちまちの多くの人が関わってバギーになりがちなプロジェクトでは、安全をとってmemset(str, '\0', sizeof(str))
を採用していました。
投稿2015/12/17 07:50
総合スコア9392
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
こんにちは。
振り返ってみると、スキル的にNULL終端をし忘れそうな時は、memset(str, '\0', sizeof(str));
してました。ある程度Cに熟練してきて、それがあり得なくなったらstr[0] = '\0';
を使ってました。
今は、変数についてはCの文字列を使いません。C++のstd::stringがほとんどです。
定数についてはCの文字列が軽いので良く使いますけど、定数だから「初期化」の概念はないです。
(std::const_stringが欲しい!!)
投稿2015/12/17 07:21
総合スコア23272
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
原則としては
C
1memset(str, '\0', sizeof(str));
だと思います。
C言語は言語として文字列型をサポートしていませんので、
char str[31+1] が後でどのように使用されるかはわかりません。
(プログラムを書く人しだいです。)
ですので、あくまでも「要素数31+1の char 型配列の初期化」と考えるべきだと思います。
「原則としては」と書きましたが、
スピードを重視するプログラムや配列がとても大きい場合など、
状況に応じてリスクを覚悟したうえで細心の注意を払ってコーディングする前提で、
初期化しなかったり、簡易な初期化で済ますことはあると思いますが、それは例外と考えるべきでしょう。
投稿2015/12/17 05:57
総合スコア1193
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
char配列を文字列領域として使うことが前提なら、「初期化」でしたらこんな感じです。
C
1char str[31+1] = ""; // = {0};でもいいけど、この方が文字列っぽさを表現できる
「空文字列にしたい」というのであれば、
C
1str[0] = '\0';
です。
基本的にmemset
は使わないことにしています。
追記
最近(というか21世紀に入ってから)は純粋なC言語を使うことがなくなったので、使い捨てのバッファー領域でもない限り、Chironianさん同様、char配列を文字列として使うことはなくなりましたね。STLコンテナのarray
はたまに使います。
C++
1std::array<char, 31+1> str; 2str.fill('\0'); // 全クリア
投稿2015/12/17 10:13
編集2015/12/17 10:24総合スコア5938
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
私は
c
1char str[31+1] = { 0 };
と書いてます。言語仕様的に正しいというのをどこかで読んだか教えてもらいました(ちゃんと調べてないところがまだまだですが)。文字配列に限らず、配列の初期化は上記の書き方をすれば、構造体の配列であっても、適切に初期化されるためです。
また言語仕様的には下記のような書き方も可能らしいです。個人的には使っていませんがご参考まで。
c
1char str[31+1] = { };
投稿2015/12/17 05:52
編集2015/12/17 05:55総合スコア3041
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。