- ベストアンサー
文字列入力について
いつも大変お世話になってます。 文字列の扱いがどうも苦手なようなのでまた教えていただきに参りました。 今回は文字列の最大長を指定せずに入力時に幾らでも書けるプログラムを書きたいと思ってます。 int main() { ↓★最大長を指定しない char* buff=""; //初期化 printf("文字列入力\n"); if(gets_s(buff,sizeof(buff)-1) == NULL){ printf("NULL\n"); } ~~~~別処理~~~~ printf("%s\n", buff); return 0; } 文字列を入力したところで別処理に入る前にエラーが出て強制終了します。 aaa.exe の 0x10259554 でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x00415986 に書き込み中にアクセス違反が発生しました。 こういったエラーはポインタの扱い方に誤りがあるのでしょうか? また、最終的に文字列の最大長を指定せずに宣言し、入力できるように するにはどのようにしたらよろしいのでしょうか?
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
>では、該当文字列の最大長を指定せずに必要に応じてメモリを確保するのはC言語では不可能なのでしょうか? その通りです。 従って、この場合、現実的には、コマンドラインから打ち込めるであろう最大の文字数以上のサイズを確保するのが、現実的な解決方法です。 このサイズはwindows-xpの場合8191文字とされています。(参考URL参照) ですので、 char *buf = malloc(8191以上のサイズ); とするのが、現実的な解決です。 また、gets_s(buff,sizeof(buff)-1)ではなくて、 gets_s(buff,上で指定したサイズ-1)とします。 sizeof(buff)の値はポインター自身のサイズなので4になります。 (厳密には32ビットモードでコンパイルした場合4になります) 「該当文字列の最大長を指定せずに必要に応じてメモリを確保する」ことを期待される気持ちは分かりますが、C言語ではサポートしていません。(perl,ruby等の高級言語ではできます。但し、perlの内部では、メモリが足りなくなると、また自動的に追加で確保し直すと言う、実に泥臭いことをやっています。perl,rubyはC言語でつくられています)
その他の回答 (3)
- yaemon_2006
- ベストアンサー率22% (50/220)
>C言語での文字列というのはNULLで終わっているchar型配列データです。 文字列の終端は、'\0'(空文字)であって、NULL(空ポインタ定数)じゃない。 >>では、該当文字列の最大長を指定せずに必要に応じてメモリを確保するのはC言語では不可能なので>しょうか? >その通りです。 現行の C(C99)では、可変長配列が使える、といっても、 文字列を取得する前にその領域を確保する必要があるので、 どちらにせよ、質問者が意図しているであろうことは、無理。
- i-kujou
- ベストアンサー率50% (13/26)
http://okwave.jp/qa4381249.html での皆さんの回答の意味が分かっていたのなら、このようなコードは書かないはずですが…… C言語での文字列というのはNULLで終わっているchar型配列データです。決して「文字列型」みたいなものが存在するわけではありません。 > char* buff=""; というものは配列 {NULL} というchar型配列を作成し、buffはそこのアドレスを指す、ということを意味します。 配列のサイズは1ですから、1つ以上のデータを追加しようとすれば当然確保した長さ以上の領域に書き込んでしまうため、エラーが発生します。 ポインターの扱い方、というよりC言語における文字列の基本を理解していないためです。 最大長を指定せずに宣言するのでしたら、#1の回答の方と同じになりますが、 > char *buff = NULL; でとしておいて、必要に応じてmalloc/freeで文字列用の配列領域を確保することになります。 また、gets_s や scanf などの文字列入力関数において、「該当文字列の最大長を指定せずに必要に応じてメモリを確保する」というようなことはできません。
お礼
では、該当文字列の最大長を指定せずに必要に応じてメモリを確保するのはC言語では不可能なのでしょうか?
- php504
- ベストアンサー率42% (926/2160)
char* buff=""; //初期化 これだと buff は書き込みできない場所を指しているので、これに書き込もうとするとアクセス違反になります。 最大長を指定しないなら動的確保になるので足りなくなったらrealloc でメモリ追加していけばいいでしょう
お礼
なるほど・・ しかし、初期化をしないと初期化をしろと警告が出るのですが これについての対策は何ができますでしょうか?
お礼
非常に参考になりました。 ありがとうございました!