- ベストアンサー
C言語の配列問題
- キーボードから入力したアルファベットの大文字(A~Z)の入力回数をそれぞれ数え、結果を画面出力するプログラムを作成せよ。入力の終了はEOFとし、配列を用いる。
- キーボードから番号(数字)を入力し、その番号に該当する文字列中の文字を画面表示するプログラムを作成せよ。数字以外の文字が入力された場合や文字列の範囲外の数字が入力された場合は、メッセージを出力し再入力を促す。
- C言語の配列問題に関して困っています。解決策を教えてください。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
naturalです。 またまたコメント読みました。 では詰まっている点からお答えしていきます。 switch文の使い方と言うことですが、基本はこうですよね。 switch(式) { case 値1: 処理 break; case 値2: 処理 break; ・ ・ ・ default: 上記以外の場合の処理 break; } 尚、各case中のbreakの意味はお解りでしょうか? これが無いと何れかのcaseに合致した場合にそれ以降のcaseの処理を全て通ってしまうので強制的に抜けてやらなくてはならないのです。 (敢えてbreak無しを利用することもありますが今回は必要ないでしょう) さて、恐らく悩まれているのは式と値の部分ですよね? この問題の場合「式」には入力された文字、つまり文字を入れるために用意した変数を指定します。 次に各caseの値ですが、何度か述べている様に文字コードが数値になっていますのでそれを指定すればよいのですが、可読性を上げるために文字定数を使用しましょう。 例えば「case 'A':」と言った具合にです。 各case内での処理はよろしいですね? それぞれに対応するカウンタ(配列で用意したもの)をインクリメントするだけです。 尚、この問題の場合defaultは不要なのですが付ける癖をつけておいた方が良いと思われますので空処理でも付けておきましょう。 さて、このswitchをどこで使用するのか、ということも悩まれている点では無いかと思いますので簡単に流れも書いておきますね。 尚、「|」の部分はネストしていることを表しています。 1.変数の定義・初期化 2.永久ループ |2-1.一文字入力 |2-2.EOFの入力がなかったか判定 ||あった場合永久ループを抜ける |2-3.入力文字の判定(switch文を使用) ||2-3-1.'A'の場合の処理 ||・ ||・ ||・ ||2-3-26.'Z'の場合の処理 ||2-3-27.default(空処理) 3.結果表示 次にif文をどこで使用するのか、ということなのですがswitchの部分を全てif文で書くことも出来ますよね? しかしこれは煩雑で見辛いのでswitch文にしましょう、ということです。 強いて言えば永久ループを抜ける条件「EOF」を判定するときに必要になります。 さて、永久ループを抜けたら何をすれば良いでしょうか? カウントした結果を表示するだけですよね。 この辺りは実行例とかが示されているかもしれませんのでそれに従ってください。 以上ですが、また解らない点がありましたらコメントください。 それでは、頑張ってください。(^_^)
その他の回答 (4)
- natural
- ベストアンサー率37% (419/1115)
naturalです。 コメント読みました。 まず最初にお断りしておきます。 この回答文は長いです。(^_^) ではポイントをいくつか見ていきましょう。 入力部分から書いていくと全部書いてしまいそうなので省略します。 まず1番からです。 >入力回数のカウントには、配列を用いるものとする。 とありますが、まずこの部分はご理解されていますでしょうか。 ここはカウンターの配列を用意するわけです。 カウントをとるわけですから整数型を扱うものであれば良いですね。 一般に数値を扱うときにint型を嫌う向きもあります(移植性の問題等で)が、練習問題のようですからここは単純にintで行きたいと思います。 例えばこうですね。 int upper_cnt[26]; 何故26個の配列になるかはお解りですね。 'A'~'Z'の個数をそれぞれ記録するエリアが必要になりますのでこのようになるわけです。 勿論個数をカウントするためには各要素はゼロでクリアしておく必要があります。(ゼロクリアする方法はまずは自分で考えてみましょうね) 例えば'F'という文字が入力されたのが判ったらupper_cnt[5]をインクリメントするわけです。 配列の要素と添え字の関係はよろしいですよね。 'F'の個数をカウントする場所が5番目になる訳がわかっていればOKです。 さて問題の文字を判定する方法ですが、例えば判定すべき文字がchar型の変数mojiに入っているとします。 'F'かどうかを判定するのであればif文を用いると次の様になります。 if(moji == 0x46) { カウントの処理; } 0x46は'F'の文字コードです。 でもソースとしてはとても読み辛いですよね。 そこで文字定数を使用します。 if(moji == 'F') { カウントの処理; } そう、先程から本文中で使用していた'F'(シングルクォーテーションで囲うます)は文字定数なのです。 これを用いることによりその文字の持つ値(文字コード)を引用したのと同じ状態を得ることが出来ます。 さてこのまま全ての条件をif文で書いていっても良いのですが、これまた煩雑になりますよね。 そこでswitch文を使用します。 ソースを載せてしまうともう回答になってしまいますので使い方は考えてみてください。 解らなかったら別途ご相談下さい。 そうそう余談ですが、前回構文を使わない方法と書きましたが、最低限if文が一つ必要でした。 さて、2番についてです。 何故数値ではなく数字(文字)を入力するかというと、数字以外の文字の判定が問題の中に盛り込まれていますよね。 これは文字コード(または文字定数)を用いて入力された数字を判定せよと言う意味だと思います。 では数字で構成された文字列の入力を前提に考えてみましょう。 入力されたのが16だとします。(このように複数桁の入力もあるわけですから文字列で入力を受けます) これは'1'、'6'、'\0'という3つの文字で構成された文字列の入力があったことを意味します。 '\0'はヌル文字で、C言語の文字列はこれを付加することで完成します。 勿論この場合自分で付加するのではなく文字列入力のための関数が行ってくれます。 次に加工に移りますが、まず加工後の数値を格納する変数を用意しておきます。 で、当然ゼロで初期化しておきます。 では加工処理に移ります。 文字列の先頭から、つまり数値としては上位桁から加工していきます。 最初の文字は'1'ですが、これを数値の1に変換したいと思います。 この辺りも関数を使用すれば簡単なのですが、ここは練習問題と言うことできちんとやってみましょう。 1から0を引いたら1ですよね。 また、6から0を引いたら6ですよね。 これと同じことが文字定数でも成り立ちます。 '0'から'9'の文字コードは連続した値で割り振られているためです。 ですから最初に取り出した上位桁の文字'1'になにをすれば数値の1にできるかはもうお解りですね。 同じ処理が'0'~'9'の全てに対して有効ですので処理は共通となります。 で、取り出し終わったら変換後の値を先程用意した数値用の変数に加算します。(ここポイントです) 次に下位の桁の加工に移行しますが、その際に今の数値用変数は10倍しておきます。 何故でしょう? 次の桁を同様に加工した後に加算することを考えれば解りますよね。 この加工処理をヌル文字に当たるまで繰り返します。 尚、10倍する処理の入れる場所によって処理が大分スッキリするのですが、この辺は作りながら考えてみてください。 勿論この間に文字の判定はしなければなりません。 一つでも数字ではない文字が混ざっていればエラー処理に移ります。 この判定も難しくはないですよね。 先程述べたとおり数字のコードは連続した値です。 つまりその範囲外であれば数字ではない、ということです。 この判定も勿論文字定数を用いて行いましょう。 最後に加工の結果得られた数値を添え字として文字列の要素を表示するわけですが、その前にこの数値が配列の要素数をはみ出していないかチェックすればOKです。 1番、2番ともに再入力等の処理の指定や表示方法に指定があれば問題に従ってください。 また、1番に関してはmojiというchar型の変数を使用していますが、こちらも問題の意図によって文字列を使用したりしますので、よく読んで解いてみてください。 ご不明の点がありましたらまたコメント下さい。 それでは頑張って下さい!
- ponnta
- ベストアンサー率17% (31/179)
配列を使うならAが(ゼロ)になるように計算すると楽かな
- coolguys
- ベストアンサー率18% (351/1917)
1.力技で一つづつswitch-caseで判断してみては? で、見つけるごとに+1していくとか。 2.これもまた、同じようにして、見つけたら表示ということですね。
- natural
- ベストアンサー率37% (419/1115)
問題と言うことでヒントだけ。 まず1番についてです。 大文字'A'~'Z'は文字コード表で見れば文字コードと呼ばれる数値にすぎません。 数値ですからそのまま比較できる訳です。 素直に文字コードを記述してやっても良いですが可読性が落ちますのでここは文字定数を使いましょう。(文字定数についてはテキストで調べて下さいね) でもif文で全ての分岐を記述していては煩雑になりますのでここは別の文(自分で考えましょう)を使います。 構文を使うよりもっとスッキリする方法があるのですがここではきっと求められていないでしょう。 次にEOFが入力されたかどうかですがこれは使用する入力関数の仕様を見てみましょう。 返却値等で確認できるはずです。 配列の扱いについて解らなかったら別途コメント下さい。 次に2番の数字の入力ですが、ここでポイントになるのは入力されているのは実は文字(複数桁もあるので文字列)だと言うことです。 文字の1と数値の1は別物です。 文字コード表に載っている1と言う文字の値が文字の1の持つ値です。 数値の1は値1でそのままですね。 つまり入力されたままの状態の1を見てその数字番目の配列要素を見ても1番目の文字は出てこないのです。 だから文字の1を数値の1に、文字の2を数値の2に変換する仕組みが必要になります。 これらの処理は関数でも出来ますが恐らく問題の意図として使用不可なのではないでしょうか。 この処理のヒントは、数値の1から数値の0を引いたら値は1ですよね。 では文字の1から同様の結果を出すには? あとは取り出した値がどの桁に収まるべきか処理するだけです。 (例えば12は1と2の文字で出来てるけれど10と2にならなければいけませんよね) ちょっと書きすぎたかも知れませんのでこの辺にしておきます。
補足
考えてみましたがどーしてもプログラムが書けません。 少しでいいんで教えてください。
補足
すいません、またいきづまってしまいました。1の問題のswitch文のところがよくわかりません。それとif文をどこで使うのかがわかりません。よろしくお願いします。