• ベストアンサー

縦の棒グラフ

こんにちは。30代のプログラム初心者です。 C言語で一日毎の平均気温に合わせて、「*」印を下図のようなイメージで表示する棒グラフを作成したい(5℃なら*を5つ表示)のですが、丸1日試行錯誤してもうまくいきませんでした。 ちなみに配列kionには、一日毎の気温を格納しています。 int kion{5,4,3,・・・}; (℃) 10| 9| 8| 7| 6| 5| * 4| * * 3| * * * 2| * * * (以下省略) 1|_*_* *_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 0 1 2 3 4 5 6 7 8 9 10 11 12 ~(以下省略) 横のメモリの _ _ _ _ _ _ _ _ _ _ _ _ _ 0 1 2 3 4 5 6 7 ・・・ は、普通にprintfで表示させているのですが、 縦の 10| 9| 8| 7| 6| 5| の表示がうまくいきません。 二次元配列を使っているのですが、やりかたが悪いんだと思います。 アドバイスを頂ければありがたいです。よろしくお願い致します。

  • DT50
  • お礼率95% (504/530)

質問者が選んだベストアンサー

  • ベストアンサー
  • yonfa
  • ベストアンサー率52% (22/42)
回答No.2

こんな感じでどうでしょう? for (i = 10; i > 0; i--){  // 気温iのメモリ表示  printf("%dl", i);  // グラフ表示  for (j = 0; j < 10; j++){   if (kion[j] >= i){    printf("*");   }   else{    printf(" ");   }  }  // 改行  printf("\n"); } 一応、グラフまで表示できるようにしました。 ただし、このままでは、気温や日数の桁数が変わるとグラフががたがたになると思います。 質問者様がプログラミングの自己学習されているという判断でよいのでしょうか? 後は自力できれいな表示ができるようにがんばってください。

DT50
質問者

お礼

ご回答ありがとうございました。 これを見る前に、自分で大体解決できてしまいました(^-^;。 こちらも参考にさせて頂きます。

その他の回答 (2)

  • noocyte
  • ベストアンサー率58% (171/291)
回答No.3

グラフ本体を表示するコードは #2 さんが書かれていますので, 左側の目盛と縦線 ('l' (エル) はやめた方がいいですよ(笑)) を出力するヒントだけ. ・縦目盛の最大桁数が事前にわかっている場合  仮に3桁とすると,   int y; // 縦目盛の値   printf("%3d|", y); ・縦目盛の最大桁数が事前にわかっていない場合  (1) 表示するすべての縦目盛の値から,それらの最大桁数を求める.    個々の値yの桁数を調べるには,sprintf() を使ってyの値を文字列に変換し,    strlen() でその長さを求めればよい.  (2) 縦目盛りの最大桁数を maxWidth とすると,次のようにすれば目盛の値yを    maxWidth 文字分の幅 (右詰め) で出力できる.     int maxWidth; // 縦目盛りの最大桁数     int y; // 縦目盛の値     printf("%*d|", maxWidth, y); 詳しくは,マニュアルの printf,sprintf,strlen の説明を読んでください.

DT50
質問者

お礼

ご回答ありがとうございました。 これを見る前に、自分で大体解決できてしまいました(^-^;。 こちらも参考にさせて頂きます。

  • yukimican
  • ベストアンサー率70% (112/159)
回答No.1

質問の意図がよくわかりません。 現在どのような出力になっていて、どうしたいのかを はっきりと書いて頂ければ、的確なアドバイスができると思います。 また、「やりかたが悪い」と書かれても、そもそも どういうやりかたをしているのかわからないので、 処理の概要 または ソースコードを書いていただけると助かります。

DT50
質問者

お礼

どうも済みませんでした。 縦軸に表示するところからやっていたのですが、それすらできません。 まず二次元配列の1列目・1行目から1列目・10行目までに10から1の数字を置き、2列目の全ての行に区切りとしての「l(エル)」を置こうと思い、このようにしてみました。 この後、配列kionに格納された値に応じて「*」を1日ごとに表示させたいと思っています。1日目の気温を「*」で5つ縦に表示、2日目の気温を「*」で4つ縦に表示・・・という具合にです。 まだ説明が下手かもしれませんが、意図が伝わらないのでしたら追記させていただきますので、ご指摘ください。   よろしくお願い致します。 #include <stdio.h> #include <ctype.h> int main() { /* int kion[10] = /* 一日ごとのkionを格納する配列 (本当は28にしたいのですが、長くなるのでとりあえず10でお願いします。)*/ /* { 5,4,3,8,7,5,2,6,4,5 };*/ int i; int j; int g[10][10] = {}; for (i = 10 ; i > 0 ; i--) { g[10 - i][0] = i ;     g[10 - i][1] = l; } for (i = 0 ; i < 10 ; i++) { for (j = 0 ; j < 10 ; j++) { putchar(g[i][j]); } printf("\n"); } printf( "-----------------------------------\n"); /* 横軸に 日付を一日毎に表示。 */ printf( " " ); for(i = 1 ; i <= 10 ; i++) { printf( " %2d " , i); } printf( "\n" ); return 0; }

関連するQ&A

  • エラー:浮動小数点の不正な使用

    /*月ごとの平均気温・降水量を構造体の配列に格納した後、 */ /*年間平均気温、年間平均降水量を求めるプログラムを作成せよ。*/ #include<stdio.h> void main(void) { int i; double total_kion, total_suiryo, av_kion, av_suiryo; struct YEAR_DATA{ double kion[12]; double suiryo[12]; }; struct YEAR_DATA data[12] = {{3.6, 50},{4.3, 61},{7.5, 98},{13.5, 153},{18.0, 162},{21.7, 210}, {25.6, 218},{26.8, 170},{22.8, 209},{16.9, 121},{11.4, 74},{6.2, 48}}; for(i=0 ; i<12 ; i++){ total_kion += data[i].kion; total_suiryo += data[i].suiryo; } av_kion = total_kion / 12; av_suiryo = total_suiryo /12; printf("年間平均気温 %lf\n", av_kion); printf("年間平均降水量 %lf\n", av_suiryo); } 構造体のところを勉強しています。 上の問題を解いてみたのですが、for文の中の2行に「浮動小数点の不正な使用」というエラーが起こってしまい、答も違っています。 どこが間違っているのか、ご指摘お願いします。

  • 実際の気温の日ごとのアップダウンは棒グラフで表すと

    実際の気温の日ごとのアップダウンは棒グラフで表すとかなりジグザグなのに、 予報の気温の日ごとのアップダウンは棒グラフで表すとなだらかなことが多いのはなぜですか。 12℃と予想された実際の気温は16℃で、 次の日で11℃と予想された実際の気温は7℃で、 予報では1℃差しかなかったのに、実際は9℃差にもなることがありました。 週間天気予報の気温の予想は実際には大きく外れてこうなることがあることを考慮していません。

  • テキストファイルから文字列を読み込んで二次元配列に格納するには

    毎回お世話になっています。 ただいまC言語を勉強中の学生です。 基本的な文法は頭に入れたつもりでしたが、まだポインタと ファイルの入出力に苦手意識があり 実際うまくできないでいるので どなたか ご存知の方にアドバイスいただければと思って書き込ませていただきます。 今回練習しているのは 先に述べたように、テキストファイルに abc def ghi jkl などと文字列を書いておき、そのファイルを読み込んで 二次元配列に格納したいのですが、何を勘違いしているのか、 うまく実現できません。 参考書などを見て 一次元配列へ格納する場合は できたようなのですが、今後このプログラムを発展させる段階で 二次元配列に文字列を 格納できたほうが好都合なので 今模索しています。。。 ちなみに 一次元配列に格納する場合は 以下のように書きました。 #include<stdio.h> #include<stdlib.h> main() { char a[10]; FILE *fp; fp = fopen("word.dat", "r"); if (fp == NULL) { printf("File does not exist.\n"); exit(1); } while(fscanf(fp,"%s",a)==1){ printf("%s\n",a); } fclose(fp); return 0; } 実はコレに関しても分からない点があり、それは 目的の配列変数 a[]に格納できたのだから それを確認したいと思い printfで a[0]~a[10]を表示してみようとしたところ 変に文字化け したものが表示されたり、何も表示されなかったり よく分からないことが起きます。私は何を勘違いしてしまっているのでしょうか(>_<) 長々と書いてしまいましたが、今回 御教授いただきたいのは (1)、テキストファイルから 英字の文字列を読み込んで二次元配列に格納するために用いるのに 一番最適な関数はどれか(fscanfやfgetsなど) そして、その関数を使って 一番シンプルな記述をするにはどのように記述すればよいのか (2)、上のようなプログラムの書き方で、配列aにテキストファイルから読み込んで格納できたようなのに、a[0]~a[10]をprintfしたときに うまく中身が表示されないのはなぜか。 という点なのですが、(1)をとりあえず急いでおりますので、(2)はおまけ程度に考えていただければと思います。 なぜかファイルの入出力がいまだに把握できなくて苦手としておりますので、どうか よろしくお願いいたします。

  • C#で、引数における一次元と二次元配列の取り扱い

    C#について質問させていただきます。 以下のようにすればそれぞれ一次元配列と二次元配列を格納出来ますが 同時に一つの引数に収めることは無理なのでしょうか?    public static void Join(string[] Ary_str){ 本文 }    public static void Join(string[ , ] Ary_str){ 本文 } そのために、例えば以下のようにしたとします。    public static void Join(object Ary_obj){ 本文 } こうすれば一次元でも二次元でも格納出来ますが 格納された値が何次元配列なのか確認するために    Ary_obj.Rank としてもエラーになってしまいます。 (1)Objectに格納した値が何次元配列なのか確認する方法か (2)一次元でも二次元でも格納できる引数の指定方法 をご存じの方、ぜひお教え願います。><

  • JavaでSwingを用いたコンボボックスの使い方

    こんにちは。 JavaでSwingを使いコンボボックスを使っています。 既にインスタンスを生成済みの空のコンボボックスに1次元配列を格納するにはどのようにしたら良いのでしょうか?いろいろ試行錯誤行いましたがうまくいきませんでした。 ★この空のコンボボックスに後から追加するにはどうしたらよいのでしょうか? JComboBox<String> a1,a2,a3; a1 = new JComboBox<String>(); a2 = new JComboBox<String>(); a3 = new JComboBox<String>(); addItemなどを使ってみましたがうまくいきませんでした。 追加するデータは1次元配列でできています。 Javaのバージョンは7です。 どうぞよろしくお願いします。

    • ベストアンサー
    • Java
  • 2次元配列とポインタ配列の違い

    2次元配列とポインタ配列の違いを比較するプログラムを作成したつもりなのですが、下のプログラムの printf("we[%d]=%u\n",i,&we[i][0]); という文がどうやら違うらしいのですが、全く分かりません。 なので、なんとなくでも構わないので分かる方がいらっしゃったらお願いします。 #include<stdio.h> int main(void) { int i; char *we[]={"Monday","Tuesday","Wednesday"}; char ek[][10]={"Monday","Tuesday","Wednesday"}; printf("2次元配列で格納したアドレス\n"); for(i=0;i<3;i++){ printf("ek[%d]=%u\n",i,&ek[i]); } printf("ポインタ配列のアドレス\n"); for(i=0;i<3;i++){ printf("we[%d]=%u\n",i,&we[i]); } printf("ポインタ配列で格納したアドレス\n"); for(i=0;i<3;i++){ printf("we[%d]=%u\n",i,&we[i][0]); } printf("ポインタ配列で格納した文字列\n"); for(i=0;i<3;i++){ printf("we[%d]=\%s\n",i,we[i]); } printf("2次元配列で格納した文字列\n"); for(i=0;i<3;i++){ printf("ek[%d]=\%s\n",i,ek[i]); } return(0); }

  • Power Point:アニメーションの設定(グラフの系列別) 

    Power Pointについて、以下のようなアニメーションを設定しようと試行錯誤しているのですが、うまくいきません。どなたか教えていただけませんでしょうか? 「折れ線グラフと棒グラフが組み合わさったグラフがあります。アニメーションによって、はじめに折れ線グラフが、その次に棒グラフが表示されるよう設定したいと思っています」 (困っていること) 「アニメーション設定」の画面で、グラフを選択し「効果の追加」を押すと、グラフ全体がオブジェクトとしてアニメーションの対象となってしまい、グラフ内の系列別に表示させることができません。

  • C言語について教えてください。

    二次元配列でまとめられた「配列で実現する文字列」の文字と文字列を表示する関数を定義し、その関数の機能を確認するプログラムを作成する。 ただし、以下の例のように文字列の個数が変更されても処理できる関数を作成する。 また、文字列の文字の個数は最大9とする(一次元配列の要素数は10とする) さらに、関数printf()をできるだけ用いない。 (1)二次元配列でまとめられたすべての文字列を「一度に」表示する関数を定義する (2)二次元配列でまとめられたすべての文字列の文字を「一度に」表示する関数を定義する。このとき、前回の課題で定義した「すべての文字を表示する関数print_all_char()」を新しく定義する関数から呼び出して用いる。 (3)二次元配列に各文字列を格納してまとめるとき、初期化ではなく、配列の宣言・定義の後で、関数strcpy()を用いること(例では、初期化によりまとめている) [例] char astr[][10] = { "ABCD", "EFGHIJ", }; [実行結果の例] すべての文字列の表示 ABCD EFGHIJ すべての文字列の文字の表示 A B C D E F G H I J [ヒント] (1)二次元配列でまとめられた文字列の文字あるいは文字列を表示する関数<返却値型><関数名>(二次元配列の受け渡しに対応した仮引数の宣言、文字列の数) (2)文字列の数を求める。二次元配列のすべての要素に文字列が格納されている場合、文字列の数=二次元配列の要素数(一次元配列の数) =sizeof(astr)/sizeof(astr[0]) ただし、sizeof演算子の生成する型はsize_t型である。 この問題について教えてください。問題丸投げだとは分かっていますがどうしても分かりません。教えてください。ちなみに前回の課題の定義は下の通りです。 void print_all_char(char *chs) { while(*chs!='\0') { printf("%c\n",*chs); chs++; } } よろしくお願いします。

  • プログラミング 問題 java

    大学のプログラミングの授業でjavaを勉強しています。 先週課題が出たのですが書き方がわかりません。 4×4の形の二次元配列Aの内容を準備し、同じく4×4の形の二次元配列Bに、下図のように90度回転するようにして移すプログラミングを作るという問題です。 わかる方いたら回答お願いします(>_<)

  • 文字列の検索と比較

    文字列の検索と比較 以下の手順に従ってプログラムを作成せよ.適宜printf を利用して,入力支援(「文字列を入 力して下さい」などの画面表示)を行うこと. (1) 文字配列name[5][64] を作成する. (2) キーボードから5 人分の名前を入力し,name 配列に格納する. (3) キーボードから名前を入力し,name 配列の何番目に格納されているかを検索して表示 する.ただし,見つからなかった場合には,「見つかりません」と表示する. (4) 「quit」が入力されるまで(3)の処理を繰り返す. という処理です・・・・・。 #include <stdio.h> int main(void){ char name[5][36]; int i; for(i = 0; i < 5; i++ ){ printf("%d番目の名前を入力:", i + 1); scanf("%s", name[i] ); } printf("五人の名前を入力しました。\n"); printf("どこに格納されているか検索します。名前を入力:"); scanf("%s",name); /* ここに配列の何番目に格納されているかを検索して表示するプログラムを作成する ただし,見つからなかった場合には,「見つかりません」と表示する. 「quit」が入力されるまで処理を繰り返す処理を書く?? */ getchar(); getchar(); return(0); } 検索された文字と入力された文字が同じであることの処理はどうすればいいのでしょうか? 二つの配列を用意してループ文?でしょうか?

専門家に質問してみよう