こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C言語での数字の花形表示

数字を読み込んで、それを花形を使った文字で表示するプログラムを書いたのですが、自分の書いたプログラムだと、読み込む数字の最初、または最後に0がくるとそれは表示してくれません・・・。
tmp-=top*s2としているから当たり前っちゃあ当たり前なんですが・・・。
そこでこのプログラムをどのように変更したら最初と最後に0を含んでいても表示できるようになるでしょうか??
やはり根本から作り直さなければいけないんでしょうか・・・。

/* 読み込んだ整数を*で表示 */
#include<stdio.h>
int main(void)
{
int no;
int dig = 0;
int top, tmp, i;
int s=1, s2;

printf("整数を入力してください:");
scanf("%d", &no);

tmp = no;
while (tmp > 0) { /* noの桁数を求める */
tmp /= 10;
dig++;
}
for (i = 0; i < (dig-1); i++)
s *= 10;

tmp = no;
s2 = s;

do {
top = tmp / s2; /* tmpの一番上の桁の数字をtopへ */

switch (top) {
case 0 : printf(" ****"); break;
case 1 : printf(" *"); break;
case 2 : printf(" ****"); break;
case 3 : printf(" ****"); break;
case 4 : printf(" ** "); break;
case 5 : printf(" ****"); break;
case 6 : printf(" ****"); break;
case 7 : printf(" ****"); break;
case 8 : printf(" ****"); break;
case 9 : printf(" ****"); break;
}

tmp -= top * s2;
s2 /= 10;
} while (tmp > 0);
putchar('\n');


tmp = no;
s2 = s;

do {
top = tmp / s2; /* tmpの一番上の桁の数字をtopへ */

switch (top) {
case 0 : printf(" * *"); break;
case 1 : printf(" *"); break;
case 2 : printf(" *"); break;
case 3 : printf(" *"); break;
case 4 : printf(" * * "); break;
case 5 : printf(" * "); break;
case 6 : printf(" * "); break;
case 7 : printf(" * *"); break;
case 8 : printf(" * *"); break;
case 9 : printf(" * *"); break;
}

tmp -= top * s2;
s2 /= 10;
} while (tmp > 0);
putchar('\n');


tmp = no;
s2 = s;

do {
top = tmp / s2; /* tmpの一番上の桁の数字をtopへ */

switch (top) {
case 0 : printf(" * *"); break;
case 1 : printf(" *"); break;
case 2 : printf(" ****"); break;
case 3 : printf(" ****"); break;
case 4 : printf(" ****"); break;
case 5 : printf(" ****"); break;
case 6 : printf(" ****"); break;
case 7 : printf(" *"); break;
case 8 : printf(" ****"); break;
case 9 : printf(" ****"); break;
}

tmp -= top * s2;
s2 /= 10;
} while (tmp > 0);
putchar('\n');


tmp = no;
s2 = s;

do {
top = tmp / s2; /* tmpの一番上の桁の数字をtopへ */

switch (top) {
case 0 : printf(" * *"); break;
case 1 : printf(" *"); break;
case 2 : printf(" * "); break;
case 3 : printf(" *"); break;
case 4 : printf(" * "); break;
case 5 : printf(" *"); break;
case 6 : printf(" * *"); break;
case 7 : printf(" *"); break;
case 8 : printf(" * *"); break;
case 9 : printf(" *"); break;
}

tmp -= top * s2;
s2 /= 10;
} while (tmp > 0);
putchar('\n');


tmp = no;
s2 = s;

do {
top = tmp / s2; /* tmpの一番上の桁の数字をtopへ */

switch (top) {
case 0 : printf(" ****"); break;
case 1 : printf(" *"); break;
case 2 : printf(" ****"); break;
case 3 : printf(" ****"); break;
case 4 : printf(" * "); break;
case 5 : printf(" ****"); break;
case 6 : printf(" ****"); break;
case 7 : printf(" *"); break;
case 8 : printf(" ****"); break;
case 9 : printf(" ****"); break;
}

tmp -= top * s2;
s2 /= 10;
} while (tmp > 0);
putchar('\n');

return(0);
}

投稿日時 - 2007-07-02 06:14:40

QNo.3132505

困ってます

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

ANo.5を更に1歩進めたのが下記のコードです。
ANo.4→ANo.5→下記
という順に、どこが変わったかを見ながらたどって下さい。
これなら理解できるでしょうか?

#include<stdio.h>

const_char_font1[10][6]_=_{
____"_****",
____"____*",
____"_****",
____"_****",
____"__**_",
____"_****",
____"_****",
____"_****",
____"_****",
____"_****"
};

const_char_font2[10][6]=_{
____"_*__*",
____"____*",
____"____*",
____"____*",
____"_*_*_",
____"_*___",
____"_*___",
____"_*__*",
____"_*__*",
____"_*__*"
};

const_char_font3[10][6]_=_{
____"_*__*",
____"____*",
____"___*_",
____"_***_",
____"_****",
____"_****",
____"_****",
____"____*",
____"_****",
____"_****"
};

const_char_font4[10][6]_=_{
____"_*__*",
____"____*",
____"__*__",
____"____*",
____"___*_",
____"____*",
____"_*__*",
____"____*",
____"_*__*",
____"____*"
};

const_char_font5[10][6]_=_{
____"_****",
____"____*",
____"_****",
____"_****",
____"___*_",
____"_****",
____"_****",
____"____*",
____"_****",
____"_****"
};



int_main(void)
{
____int_no;
____int_dig=0;
____int_top[30];
____int_tmp,i;

____printf("整数を入力してください:");
____scanf("%d",_&no);

____tmp_=_no;
____while_(tmp>0)_{_/*_noの桁数を求める_*/
________top[dig]_=_tmp_%_10;
________tmp/=10;
________dig++;
____}

____for(i=dig-1_;_i>=0_;_i--)_{
________printf("%s",_font1[top[i]]);
____}
____printf("\n");

____for(i=dig-1_;_i>=0_;_i--)_{
________printf("%s",_font2[top[i]]);
____}
____printf("\n");

____for(i=dig-1_;_i>=0_;_i--)_{
________printf("%s",_font3[top[i]]);
____}
____printf("\n");

____for(i=dig-1_;_i>=0_;_i--)_{
________printf("%s",_font4[top[i]]);
____}
____printf("\n");

____for(i=dig-1_;_i>=0_;_i--)_{
________printf("%s",_font5[top[i]]);
____}
____printf("\n");
}


なお、本来はフォントは上記のように1行目ばかりを集めるのではなく、もう1歩進めて、
const char font[10][5][6] = {
{
"____*",
"____*",
"____*",
"____*",
"____*"
}, // 1のフォント
{
"_****",
"____*",
"___*_",
"__*__",
"_****",
}, // 2のフォント
 ・
 ・
 ・
のように、1は1で、2は2で固めるのが普通です。
ここまでできれば、ANo.2に近い完成度になります。
ご自分で工夫してみて下さい。

投稿日時 - 2007-07-03 01:15:02

お礼

おおー!!たくさんのお教え、ホントにありがとうございます!!
これならなんとか理解できます!!ありがとうございます!!

プログラムって、いろんな書き方ができるけど、うまく書くとすごくシンプルでわかりやすくなるもんなんですねー・・・すごいです。

ありがとうございました!!

投稿日時 - 2007-07-09 16:01:20

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(6)

ANo.5

ANo.4のコードを多少改良してみました。
質問で提示されたコードの延長上にあるゴールとしては、こんなものでしょう。

#include<stdio.h>
int_main(void)
{
____int_no;
____int_dig=0;
____int_top[30];
____int_tmp,i;

____printf("整数を入力してください:");
____scanf("%d",_&no);

____tmp_=_no;
____while_(tmp>0)_{_/*_noの桁数を求める_*/
________top[dig]_=_tmp_%_10;
________tmp/=10;
________dig++;
____}

____for(i=dig-1_;_i>=0_;_i--)_{
________switch_(top[i])_{
________case_0_:_printf("_****");_break;
________case_1_:_printf("____*");_break;
________case_2_:_printf("_****");_break;
________case_3_:_printf("_****");_break;
________case_4_:_printf("__**_");_break;
________case_5_:_printf("_****");_break;
________case_6_:_printf("_****");_break;
________case_7_:_printf("_****");_break;
________case_8_:_printf("_****");_break;
________case_9_:_printf("_****");_break;
________}
____}
____printf("\n");

____for(i=dig-1_;_i>=0_;_i--)_{
________switch_(top[i])_{
________case_0_:_printf("_*__*");_break;
________case_1_:_printf("____*");_break;
________case_2_:_printf("____*");_break;
________case_3_:_printf("____*");_break;
________case_4_:_printf("_*_*_");_break;
________case_5_:_printf("_*___");_break;
________case_6_:_printf("_*___");_break;
________case_7_:_printf("_*__*");_break;
________case_8_:_printf("_*__*");_break;
________case_9_:_printf("_*__*");_break;
________}
____}
____printf("\n");

____for(i=dig-1_;_i>=0_;_i--)_{
________switch_(top[i])_{
________case_0_:_printf("_*__*");_break;
________case_1_:_printf("____*");_break;
________case_2_:_printf("___*_");_break;
________case_3_:_printf("_***_");_break;
________case_4_:_printf("_****");_break;
________case_5_:_printf("_****");_break;
________case_6_:_printf("_****");_break;
________case_7_:_printf("____*");_break;
________case_8_:_printf("_****");_break;
________case_9_:_printf("_****");_break;
________}
____}
____printf("\n");

____for(i=dig-1_;_i>=0_;_i--)_{
________switch_(top[i])_{
________case_0_:_printf("_*__*");_break;
________case_1_:_printf("____*");_break;
________case_2_:_printf("__*__");_break;
________case_3_:_printf("____*");_break;
________case_4_:_printf("___*_");_break;
________case_5_:_printf("____*");_break;
________case_6_:_printf("_*__*");_break;
________case_7_:_printf("____*");_break;
________case_8_:_printf("_*__*");_break;
________case_9_:_printf("____*");_break;
________}
____}
____printf("\n");

____for(i=dig-1_;_i>=0_;_i--)_{
________switch_(top[i])_{
________case_0_:_printf("_****");_break;
________case_1_:_printf("____*");_break;
________case_2_:_printf("_****");_break;
________case_3_:_printf("_****");_break;
________case_4_:_printf("___*_");_break;
________case_5_:_printf("_****");_break;
________case_6_:_printf("_****");_break;
________case_7_:_printf("____*");_break;
________case_8_:_printf("_****");_break;
________case_9_:_printf("_****");_break;
________}
____}
____printf("\n");
}

投稿日時 - 2007-07-03 00:25:14

ANo.4

「最後の0が表示されない」はナゾですね。
何かコンパイルエラーが発生して、前のexeファイルが更新されてない、とかないですか?
putchar('\n');
が1行間違っていますが、それ以外は問題なさそうですよ。
省略せずにコードを掲載します。(動作確認済み)
_(アンダーバー)は半角スペースに一斉変換して使って下さい。

#include<stdio.h>
int_main(void)
{
____int_no;
____int_dig=0;
____int_top[30];
____int_tmp,i,s;

____printf("整数を入力してください:");
____scanf("%d",_&no);

____tmp_=_no;
____while_(tmp>0)_{_/*_noの桁数を求める_*/
________tmp/=10;
________dig++;
____}

____tmp_=_no;
____for_(i=0;_i<dig;_i++)_{
________top[i]_=_tmp_%_10;
________tmp/=10;
____}

____s_=_dig_-_1;
____while_(s>=0)_{
________switch_(top[s--])_{
________case_0_:_printf("_****");_break;
________case_1_:_printf("____*");_break;
________case_2_:_printf("_****");_break;
________case_3_:_printf("_****");_break;
________case_4_:_printf("__**_");_break;
________case_5_:_printf("_****");_break;
________case_6_:_printf("_****");_break;
________case_7_:_printf("_****");_break;
________case_8_:_printf("_****");_break;
________case_9_:_printf("_****");_break;
________}
____}
____putchar('\n');

____s_=_dig_-_1;
____while_(s>=0)_{
________switch_(top[s--])_{
________case_0_:_printf("_*__*");_break;
________case_1_:_printf("____*");_break;
________case_2_:_printf("____*");_break;
________case_3_:_printf("____*");_break;
________case_4_:_printf("_*_*_");_break;
________case_5_:_printf("_*___");_break;
________case_6_:_printf("_*___");_break;
________case_7_:_printf("_*__*");_break;
________case_8_:_printf("_*__*");_break;
________case_9_:_printf("_*__*");_break;
________}
____}
____putchar('\n');

____s_=_dig_-_1;
____while_(s>=0)_{
________switch_(top[s--])_{
________case_0_:_printf("_*__*");_break;
________case_1_:_printf("____*");_break;
________case_2_:_printf("___*_");_break;
________case_3_:_printf("_***_");_break;
________case_4_:_printf("_****");_break;
________case_5_:_printf("_****");_break;
________case_6_:_printf("_****");_break;
________case_7_:_printf("____*");_break;
________case_8_:_printf("_****");_break;
________case_9_:_printf("_****");_break;
________}
____}
____putchar('\n');

____s_=_dig_-_1;
____while_(s>=0)_{
________switch_(top[s--])_{
________case_0_:_printf("_*__*");_break;
________case_1_:_printf("____*");_break;
________case_2_:_printf("__*__");_break;
________case_3_:_printf("____*");_break;
________case_4_:_printf("___*_");_break;
________case_5_:_printf("____*");_break;
________case_6_:_printf("_*__*");_break;
________case_7_:_printf("____*");_break;
________case_8_:_printf("_*__*");_break;
________case_9_:_printf("____*");_break;
________}
____}
____putchar('\n');

____s_=_dig_-_1;
____while_(s>=0)_{
________switch_(top[s--])_{
________case_0_:_printf("_****");_break;
________case_1_:_printf("____*");_break;
________case_2_:_printf("_****");_break;
________case_3_:_printf("_****");_break;
________case_4_:_printf("___*_");_break;
________case_5_:_printf("_****");_break;
________case_6_:_printf("_****");_break;
________case_7_:_printf("____*");_break;
________case_8_:_printf("_****");_break;
________case_9_:_printf("_****");_break;
________}
____}
____putchar('\n');
}

投稿日時 - 2007-07-03 00:14:14

ANo.3

★回答者 No.1 です。
>printf("整数を入力してください:");
>scanf("%d", &no);
 ↑
 この部分を文字列として入力するようにします。
 つまり
 char input[ 256 ]; ←宣言に追加
 
 printf( "整数を入力してください:" );
 scanf( "%s", input );
 ↑
 このようにします。
・そしたら input[0] ~ input[len - 1] までを順番に処理します。
 このとき、input[n] は数値ではなく文字 '0'~'9' になるため switch 文の case には
 シングルクォーテーション(’)をつけて下さい。
 
 switch ( input[i] ){
  case '0': printf(" ****"); break;
  case '1': printf("  *"); break; ←修正
  case '2': printf(" ****"); break;
  case '3': printf(" ****"); break;
  case '4': printf(" * *"); break; ←修正
  case '5': printf(" ****"); break;
  case '6': printf(" ****"); break;
  case '7': printf(" ****"); break;
  case '8': printf(" ****"); break;
  case '9': printf(" ****"); break;
 }
 putchar( '\n' );
 ↑
 こんな感じになります。
・とにかく scanf() の時に数値ではなくて文字列で入力しないと先頭の 0 や末尾の 0 が
 正しく表示されません。あと文字列の入力しているので i カウンタなどで添え字の番号を
 0 ~ 文字数-1 までを処理すれば左から右へ数字を順番に扱えます。
>tmp = no;
>while ( tmp > 0 ){ /* noの桁数を求める */
> tmp /= 10;
> dig++;
>}

>tmp = no;
>for ( i = 0 ; i < dig ; i++ ){
> top[i] = tmp % 10;
> tmp /= 10;
>}
 ↑
 文字列で入力してその配列を扱うため、上の部分は必要なくなります。
 逆にこの部分を記述しているのでせっかく配列に桁毎にセットしても先頭/末尾の 0 が
 うまく表示できないのです。
・ちなみに上記の方法では整数の下位の桁から順番に top[i] に入れることになりますよ。
 つまり、12300 の場合は
 top[0]⇒0
 top[1]⇒0
 top[2]⇒3
 top[3]⇒2
 top[4]⇒1
 となります。もし期待通りに
 top[0]⇒1
 top[1]⇒2
 top[2]⇒3
 top[3]⇒0
 top[4]⇒0
 とするには次のようにします。
 tmp = no;
 for ( i = (dig - 1) ; i >= 0 ; i-- ){
  top[i] = tmp % 10;
  tmp /= 10;
 }
 となりますが…。
・以上。

投稿日時 - 2007-07-02 18:53:52

お礼

なるほどー・・・・文字列で入力を読み取るのですね。参考になります。

 tmp = no;
 for ( i = (dig - 1) ; i >= 0 ; i-- ){
  top[i] = tmp % 10;
  tmp /= 10;
 }

↑たしかに・・・ありがとうございます<(_ _)>

投稿日時 - 2007-07-09 15:58:26

ANo.2

携帯(PCサイトビューア)からなので手短に。
最初に桁数を求め、1桁ずつ配列に入れておけば、毎回求める手間も省けるし、最後の0も表示できます。
桁数を入力させるようにすれば、先頭に0を表示することもできますよ。

投稿日時 - 2007-07-02 10:41:20

お礼

ありがとうございます!!配列を使ってやってみました。
ですが、これでも最後に0がくると表示されないのですが、どこが悪いのでしょうか・・・。すいません・・・。

/* 読み込んだ整数を*で表示 */
#include<stdio.h>
int main(void)
{
int no;
int dig=0;
int top[30];
int tmp,i,s;

printf("整数を入力してください:");
scanf("%d", &no);

tmp = no;
while (tmp>0) { /* noの桁数を求める */
tmp/=10;
dig++;
}

tmp = no;
for (i=0; i<dig; i++) {
top[i] = tmp % 10;
tmp/=10;
}

s = dig - 1;
while (s>=0) {
switch (top[s--]) {
case 0 : printf(" ****"); break;
case 1 : printf(" *"); break;
case 2 : printf(" ****"); break;
case 3 : printf(" ****"); break;
case 4 : printf(" ** "); break;
case 5 : printf(" ****"); break;
case 6 : printf(" ****"); break;
  case 7 : printf(" ****"); break;
case 8 : printf(" ****"); break;
case 9 : printf(" ****"); break;
}
putchar('\n');
}
※以下繰り返し

投稿日時 - 2007-07-02 15:16:31

ANo.1

★アドバイス
・花文字表示のアルゴリズムを変えた方がいいと思います。
 花文字のビットイメージをデータで用意して数字(0-9)を読み込んだら順番に1桁ずつ
 花文字のビットイメージより表示するようにした方がスッキリしますよ。
 switch 文で 7 セグメントを表示するよりもソースが簡単になります。
・下のそのサンプルを載せておきます。

サンプル:
#include <stdio.h>
#include <string.h>

// 花文字表示
void dispSegment( int num, int line )
{
 static long table[ 10 ][ 5 ] = {
  0x1111, 0x1001, 0x1001, 0x1001, 0x1111,  // 0
  0x0001, 0x0001, 0x0001, 0x0001, 0x0001,  // 1
  0x1111, 0x0001, 0x1111, 0x1000, 0x1111,  // 2
  0x1111, 0x0001, 0x1111, 0x0001, 0x1111,  // 3
  0x1001, 0x1001, 0x1111, 0x0001, 0x0001,  // 4
  0x1111, 0x1000, 0x1111, 0x0001, 0x1111,  // 5
  0x1111, 0x1000, 0x1111, 0x1001, 0x1111,  // 6
  0x1111, 0x1001, 0x0001, 0x0001, 0x0001,  // 7
  0x1111, 0x1001, 0x1111, 0x1001, 0x1111,  // 8
  0x1111, 0x1001, 0x1111, 0x0001, 0x1111,  // 9
 }; long image = table[num][line]; int mask;
 
 for ( mask = 0xF000 ; mask != 0x0000 ; mask >>= 4 ){
  if ( image & mask ){
   putchar( '*' );
  }
  else{
   putchar( 0x20 );
  }
 }
}

// メイン
int main( void )
{
 char input[ 256 ];
 int i, j, len;
 
 // 文字列で入力
 printf( "整数を入力してください:" );
 scanf( "%s", input );
 len = (int)strlen( input );
 
 // 上から順に表示(1-5段)
 for ( j = 0 ; j < 5 ; j++ ){
  for ( i = 0 ; i < len ; i++ ){
   dispSegment( (input[i] - '0'), j );  // 花文字表示
   putchar( 0x20 );  // スペース
  }
  putchar( '\n' );
 }
 return 0;
}

以上。

投稿日時 - 2007-07-02 08:49:00

お礼

すごい・・・・。とても参考になりました。
でもまだ関数や構造体(?)は習ってないので使えなくて・・・
すごく良いプログラムを提供してくださったのに申し訳ないです。
ところどころ勉強不足で理解できないところがあるのでもう少し勉強してからこのプログラムは使わせていただきます^^;

投稿日時 - 2007-07-02 14:49:30