ポインタと文字列
Re: ポインタと文字列
ヒント:ポインタには++演算子が使えます。
ポインタの指すアドレスを一つ進めることができます。
ポインタの指すアドレスを一つ進めることができます。
- bitter_fox
- 記事: 607
- 登録日時: 14年前
- 住所: 大阪府
Re: ポインタと文字列
まず、本題の前に、aが確保されてないのに関わらず、文字列を代入しようとしています。beginner さんが書きました:ポインタを用いて文字列を入力してその文字列を表示させる(配列を使ってはいけない)というプログラムをつくっているのですが、
文字列を入力しているときに上書きされてしまって一番最後に入力した文字しか表示されません。
入力した文字列をすべて表示させるにはどのようにするべきなのでしょうか?
出力も、n回、ポインタaの値(ここは一般にアドレスが入ってる)を文字として出力している。
もし、やるのであれば、ダブルポインタにして動的に確保するのが妥当な方法でしょう。
PS:「文字列の長さ」というよりかは、現在のプログラムでは、「文字列の個数」とした方が適切かと思います。
[hr][追記]
んん、入力される文字列は一つなのかな・・・?
今のプログラムでは、文字列を複数個入力されるのか、文字を複数個入力されて一つの文字列になるのかがはっきりしてないのですが・・・
どちらでしょうか??
Re: ポインタと文字列
h2so5さん,bitter_foxさん,コメントありがとうございます。
>>bitter_foxさん
入力する文字列は一つです。
h2so5さんにもお願いしたいことなのですが、もう少し詳しくヒントを出してもらいたいです。
>>bitter_foxさん
入力する文字列は一つです。
h2so5さんにもお願いしたいことなのですが、もう少し詳しくヒントを出してもらいたいです。
Re: ポインタと文字列
>もう少し詳しくヒントを出してもらいたいです。
「本来は」自分の脳みそをフル回転させてプログラムを完成させるのが筋である、ということはおわかりですか?
あまり詳しくヒントを出し過ぎると、答えそのものを書いてしまうことにもなりかねず、
それでは質問者さんのためにならない、という判断が働いているのではないでしょうか。
与えられたヒントを頼りに、「自分の頭や手を使って(自分で調べたり本を読んだりして)」、
完成まで持っていってみてはどうでしょう。
「本来は」自分の脳みそをフル回転させてプログラムを完成させるのが筋である、ということはおわかりですか?
あまり詳しくヒントを出し過ぎると、答えそのものを書いてしまうことにもなりかねず、
それでは質問者さんのためにならない、という判断が働いているのではないでしょうか。
与えられたヒントを頼りに、「自分の頭や手を使って(自分で調べたり本を読んだりして)」、
完成まで持っていってみてはどうでしょう。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
Re: ポインタと文字列
>もう少し詳しくヒントを出してもらいたいです。
bitter_foxさんの仰るような、プログラムの本題以前の問題が有ったのに、
そこを指摘せずにヒントを書いてしまったので、分かりにくかったかもしれません。
今度からはもう少し冷静にコードを見るようにします。申し訳ありません。
また、私の出したヒントはあくまで「配列を使わずに文字列を保持するためのポイント」を言っているだけで、
beginnerさんのコードにそれを適用すれば即動作する訳ではないことに注意してください。
(検索キーワードのような物です(´・ω・`))
bitter_foxさんの仰るような、プログラムの本題以前の問題が有ったのに、
そこを指摘せずにヒントを書いてしまったので、分かりにくかったかもしれません。
今度からはもう少し冷静にコードを見るようにします。申し訳ありません。
また、私の出したヒントはあくまで「配列を使わずに文字列を保持するためのポイント」を言っているだけで、
beginnerさんのコードにそれを適用すれば即動作する訳ではないことに注意してください。
(検索キーワードのような物です(´・ω・`))
最後に編集したユーザー h2so5 on 2011年1月19日(水) 23:41 [ 編集 1 回目 ]
- bitter_fox
- 記事: 607
- 登録日時: 14年前
- 住所: 大阪府
Re: ポインタと文字列
では、動的確保のやり方はご存知でしょうか??beginner さんが書きました: h2so5さんにもお願いしたいことなのですが、もう少し詳しくヒントを出してもらいたいです。
また、普通にchar型の配列として宣言されているhogeに対して、文字列を入力してもらうプログラムを書くことは可能ですか??(配列は十分な大きさで確保されているとする。)
次に、入力してもらったhogeを出力することは可能ですか??
あと、質問文のプログラムでは、入力と出力のアルゴリズムがそれぞれ違ってますが、何らかの指示や意図があるのでしょうか??
Re: ポインタと文字列
>>h2so5さん
分かりました。ありがとうございます。
>>bitter_foxさん
動的確保のやり方が全く分からないです。
出力と入力のアルゴリズムが違うという点なんですが、特に指示や意図といったものはありません。
コードを以下のように書き直してみたのですが、まだ表示させる段階で完璧ではありません。出力させると空欄の部分がでてきてしまいます。
そのような点を改善するにはどのようにすればよろしいですか?
分かりました。ありがとうございます。
>>bitter_foxさん
動的確保のやり方が全く分からないです。
出力と入力のアルゴリズムが違うという点なんですが、特に指示や意図といったものはありません。
コードを以下のように書き直してみたのですが、まだ表示させる段階で完璧ではありません。出力させると空欄の部分がでてきてしまいます。
そのような点を改善するにはどのようにすればよろしいですか?
Re: ポインタと文字列
まずはっきりさせたいのは、
文字列の入出力を一度にするのか、それとも1文字ずつにするのか、ということです。
beginnerさんのコードは2つが混ざっている気がします。
また、文字列を一度に入出力する方法ですと、私がヒントで言った++演算子は必要ありません。
動的確保はmallocで検索してみてください。
文字列の入出力を一度にするのか、それとも1文字ずつにするのか、ということです。
beginnerさんのコードは2つが混ざっている気がします。
また、文字列を一度に入出力する方法ですと、私がヒントで言った++演算子は必要ありません。
動的確保はmallocで検索してみてください。
Re: ポインタと文字列
>>h2so5さん
文字列の入出力を1文字ずつでやりたいです。
mallocで検索してじっくりとは調べていないのですが、あまりよい関数ではないとの表記がありました。
使っても大丈夫な関数なのでしょうか?
文字列の入出力を1文字ずつでやりたいです。
mallocで検索してじっくりとは調べていないのですが、あまりよい関数ではないとの表記がありました。
使っても大丈夫な関数なのでしょうか?
- bitter_fox
- 記事: 607
- 登録日時: 14年前
- 住所: 大阪府
Re: ポインタと文字列
これだと、確保されていないaに入力してもらって、beginner さんが書きました: コードを以下のように書き直してみたのですが、まだ表示させる段階で完璧ではありません。出力させると空欄の部分がでてきてしまいます。
そのような点を改善するにはどのようにすればよろしいですか?
bにaのアドレスを代入して。
そのアドレスの値を文字として出力しようとしてますね。
(しかも、これだと、文字列を入力してもらってその文字列を出力するというより、文字を入力してもらってそれを反復しているといった感じになってます。)
配列を使ったバージョンを書いていただけますでしょうか??
これに対する返答もお願いします。bitter_fox さんが書きました: また、普通にchar型の配列として宣言されているhogeに対して、文字列を入力してもらうプログラムを書くことは可能ですか??(配列は十分な大きさで確保されているとする。)
次に、入力してもらったhogeを出力することは可能ですか??
Re: ポインタと文字列
確かにむやみにmallocを使うべきではありませんが、beginner さんが書きました: 使っても大丈夫な関数なのでしょうか?
配列を使ってはいけないという条件付きですので、mallocを使うしかないでしょう。
そして、文字が上書きされないようにするためには、
入力されるたびに代入する場所を変える(ずらす)必要があります。そこで++を使います。
- bitter_fox
- 記事: 607
- 登録日時: 14年前
- 住所: 大阪府
Re: ポインタと文字列
取りあえず、一度じっくりと調べてみてください。beginner さんが書きました:>>h2so5さん
文字列の入出力を1文字ずつでやりたいです。
mallocで検索してじっくりとは調べていないのですが、あまりよい関数ではないとの表記がありました。
使っても大丈夫な関数なのでしょうか?
また、「あまりよい関数ではない」とのことですが、決してそんなことはないです。
むしろ、この関数がないとダイナミックなプログラミングができないです。
- bitter_fox
- 記事: 607
- 登録日時: 14年前
- 住所: 大阪府
- bitter_fox
- 記事: 607
- 登録日時: 14年前
- 住所: 大阪府
Re: ポインタと文字列
そうです、"%c"です。beginner さんが書きました:<<bitter_foxさん
一文字ずつ入力するときは"%S"ではなく"%C"です。
では、次に、さっきのプログラムを動的確保したものに変更したいのですが、まず動的確保の説明をします。
動的確保というのは、メモリを動的に確保するというテクニックです。(まんまですね。)
動的確保されるメモリは、ヒープ領域という領域に割り当てられてるメモリで、これらのメモリはOSが管理しています。
ですので、先ほども出た、malloc関数などでOSにメモリを確保してもらう必要があります。
では、その手順は、 の4つになります。
特に大事なのは、①と②と④です。
①のメモリを動的に確保する関数は、
malloc, calloc, realloc
主にこの三つが使われます。(reallocが確保の際に使われるのは稀)
また、これらの関数を使うためには、stdlib.hをインクルードする必要があります。
これらの関数の使い方は、
http://msdn.microsoft.com/ja-jp/library/6ewkz86d.aspx
http://msdn.microsoft.com/ja-jp/library/3f8w183e.aspx
http://msdn.microsoft.com/ja-jp/library/xbebcx7d.aspx
ここを読むと、「戻り値に型キャストを行います」とあります。
これは、これらの関数の戻り値の型はvoid*型のため、各々の型に変換してあげる必要があるのです。(と言ってもC言語ではvoid*は自動的に型キャストされるのでしなくても問題はありませんが、C++では明示的にキャストしないとコンパイルエラーになってしまいます。)
次に、②のメモリ確保に成功したかを調べるですが、
あれら、3つの関数は、メモリ確保に失敗するとNULLポインタを返します。
ですので、 といった風にする必要があります。
そして、③の確保したメモリを開放するは、
free関数を使います。
この関数の使い方は、
http://msdn.microsoft.com/ja-jp/library/we1whae7.aspx
を参考にしてください。
この関数で解放した後、解放したアドレスにアクセスしたりもう一度freeしたりすると、エラーが発生する可能性があるので注意してください。
これらのURL先の方が多分わかりやすいです・・・w
[参考URL]
http://homepage2.nifty.com/c_lang/intro/no_33.htm
http://homepage3.nifty.com/mmgames/c_gu ... alloc.html
http://wisdom.sakura.ne.jp/programming/c/c55.html
Re: ポインタと文字列
>>bitter_foxさん
大変丁寧に説明していただき分かりやすかったのですが、
malloc関数はあまり使わない方がよいと書いてあるサイトもあったのですが大丈夫なのでしょうか?
大変丁寧に説明していただき分かりやすかったのですが、
malloc関数はあまり使わない方がよいと書いてあるサイトもあったのですが大丈夫なのでしょうか?
- bitter_fox
- 記事: 607
- 登録日時: 14年前
- 住所: 大阪府
Re: ポインタと文字列
大丈夫です、おそらくそのサイトは、メモリリークとか解放したメモリにアクセスした際のエラーなどのこと(メモリ管理の煩わしさ)を考慮してのことでしょうが、これらの点は、あくまでプログラマの責任なので、malloc関数がどうとかそういう話ではないです。beginner さんが書きました: malloc関数はあまり使わない方がよいと書いてあるサイトもあったのですが大丈夫なのでしょうか?
また、あまり使わない方がよいというのは、動的確保に対してなのかもしれませんが、このプログラムでは、動的確保を行うようにという指示が出てるのでその点を心配するのは不毛かと思います。
PS:この件に関しては、h2so5さんもすでに返答されていますが、ご確認されましたでしょうか??
Re: ポインタと文字列
bitter_foxさんが説明されている通りmalloc関数を使用すること自体には問題がほとんどありません。beginner さんが書きました:>>bitter_foxさん
大変丁寧に説明していただき分かりやすかったのですが、
malloc関数はあまり使わない方がよいと書いてあるサイトもあったのですが大丈夫なのでしょうか?
多用することによってメモリの断片化が発生する可能性がありますが、初心者が気にするような問題ではありません。
参考のため、そのサイトのURLを教えていただけますか?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: ポインタと文字列
引用:wikipediaより。 http://ja.wikipedia.org/wiki/Malloc
これは、C++について書かれた事ですのでC言語では関係ないです。
mallocが動的確保のためバグの危険を伴うことは間違いないですが、ポインタを使っている時点でバグの危険はあります。
配列を使わず、ポインタで使用するメモリを得る方法は、C言語標準関数の範囲ではmallocでメモリ確保するしかありません。
問題は、この文でしょうか?C++でもmalloc関数は利用できるが、この利用は後述の問題を引き起こすため推奨されない。C++では言語の機能としてnew演算子、delete演算子が用意されている。mallocで確保したメモリ領域に対してdeleteしたり、逆にnewで確保した領域をfreeしたりすると結果は未定義となる。mallocによって生まれたポインタとnewによって生まれたポインタの混在はバグの温床であり、また、new/delete演算子と違い、malloc/free関数ではクラスのコンストラクタとデストラクタが呼ばれないという違いもあり、C++でのmallocは禁じ手の扱いである。
これは、C++について書かれた事ですのでC言語では関係ないです。
mallocが動的確保のためバグの危険を伴うことは間違いないですが、ポインタを使っている時点でバグの危険はあります。
配列を使わず、ポインタで使用するメモリを得る方法は、C言語標準関数の範囲ではmallocでメモリ確保するしかありません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- bitter_fox
- 記事: 607
- 登録日時: 14年前
- 住所: 大阪府
Re: ポインタと文字列
ところで、ここへの返信や
[参考URL]
http://homepage2.nifty.com/c_lang/intro/no_33.htm
http://homepage3.nifty.com/mmgames/c_gu ... alloc.html
http://wisdom.sakura.ne.jp/programming/c/c55.html
などを読んで動的確保の仕方は、理解されましたでしょうか??
[参考URL]
http://homepage2.nifty.com/c_lang/intro/no_33.htm
http://homepage3.nifty.com/mmgames/c_gu ... alloc.html
http://wisdom.sakura.ne.jp/programming/c/c55.html
などを読んで動的確保の仕方は、理解されましたでしょうか??