- ベストアンサー
文字化けして表示される。
本プログラムは、8色の色(白、黒、赤、青、黄、緑、橙、茶)から四文字を選択して重複なく表示させるプログラムです。 ところが、表示させるときに文字化けして「菌数」などと文字化けして表示されてしまいます。 これはなぜなのでしょうか? #include<stdio.h> #include<stdlib.h> #include<time.h> int main(void) { char *iro[8]={"白","黒","赤","青","黄","緑","橙","茶"}; int x,i,j; char atesase[4]; srand(time(NULL)); /*重複をなくすための処理*/ for(i=0;i<4;i++) { do{ x=rand()%8; for(j=0;j<i;j++) { if(atesase[j]==x) { break; } } }while(j<i); atesase[i]=x; } /*表示させるための処理*/ for(i=0;i<4;i++) { printf("%c",iro[atesase[i]][0]); } return 0; }
- みんなの回答 (10)
- 専門家の回答
質問者が選んだベストアンサー
自分が分かってないこと力説されてもねぇ・・・ (だからやってみればわかるとまで書いたのに) 戻って >初心者で独学なもので分かりやすいコードとにくいコードの違いがまだよくわかりません 自分だけで全て最後まで面倒見るプログラムや そのときだけのプログラムならどんなコードかいても 自分が悩めば良いだけですが 後から自分で見たとき・人が見るときに今回の回答者さんのように ずれた原因だと思いこんで余計悩むことがあるってことです 解決はしてるようですし↑だけ書くのも無駄なんで 主に#4の以下部分への補足として書きます >#1さんが言われているようにマルチバイトに対応してません >1キャラ持ってくるだけですので本来得たい漢字になりません >それが合成されるんで「菌数」のような文字になるわけです 全角1文字というのはデータとして2バイトで構成されています 以下のようになります ()内がその文字のS-JISコード 白(9492)・黒(8d95)・赤(90d4)・青(90c2) 黄(89a9)・緑(97ce)・橙(9ef2)・茶(9283) printf関数内で指定しているのは"%c"ですので 1バイト(1キャラ)のデータのみ表示されます 表示の際に改行なども入っていないため ランラムに4個選択された漢字の先頭1バイトが4個立て続けに表示され 該当する文字が2文字の漢字コードになって表示されていたはずです でも 菌 に該当するコード(8bdb)が見当たらないのはちょっと気になります (書き間違いかな?なんて思ってます) 数 の方はコードが9094なので表示の可能性はありますけどね
その他の回答 (9)
- himajin100000
- ベストアンサー率54% (1660/3060)
>#8 最初ミスったと思っているけど、質問者さんの#2のコメントが正しい気がする。(#4,#6は同じことを言っている) >に有る通り、未定義なときは for(j=0;j<i;j++) { } の真ん中は j = 0 かつ i = 0だから j < iを満たさず、【ループを飛ばす】ので比較は行われない。 atesase[i]=x; で atesase[0] = x; が実行されるから問題ない。
- asuncion
- ベストアンサー率33% (2127/6289)
何だか全然わかっていない人がいますが…。 >char atesase[4]; 関数内部の自動変数ですので、定義しただけでは 何が入っているかわからない、というのは、C言語の「仕様」です。 >for(j=0;j<i;j++) >{ >if(atesase[j]==x) jが0の場合を例に挙げます。 このif文でatesase[0]とxとが等しいかどうかを判断しています。 ということは、これよりも「前で」、atesase[0]とxとに 適切な値が入っていなければなりません。ここまではわかりますね。 xには、rand関数を用いた値が入っています。ところが、 atesase[0]には、前述のとおり、何が入っているかわかりません。 それを比較に使ってはいけない、と申しております。
- 和泉 博(@hiroshi09s)
- ベストアンサー率54% (59/109)
#1さんが正解ですが、要は、このプログラムの間違いは最後の printf()部分だけですよ。 /*表示させるための処理*/ for(i=0;i<4;i++) { printf("%c",iro[atesase[i]][0]); } ↓↓↓ 以下のように訂正するだけでOKですよ ↓↓↓ /*表示させるための処理*/ for(i=0;i<4;i++) { printf("%s ",iro[atesase[i]]); } printf("\n");
- koi1234
- ベストアンサー率53% (1866/3459)
#5追記 補足ちゃんと見てませんでした 御自身で#2さんに補足してるのと同じことです ちなみに今回の場合で言えばatesase変数はintでもcharでも問題ありません (charは文字 という意味ではなく 1バイトであらわせる数値としても使えます)
- koi1234
- ベストアンサー率53% (1866/3459)
>どういう意味なのでしょうか?お手数ですがよろしくお願いします。 其処のif文が実行される(これを 判断が走る と表現しただけ)時は atesase変数にはちゃんと値が代入されているので他の方の指摘にある >何が入っているかわからない状態です。 というのは当てはまりません という意味です
- koi1234
- ベストアンサー率53% (1866/3459)
実際にやってみればわかりますが 指摘されている判断が走るときは値が代入されています 根本的な問題は其処ではありません (でも分かりづらいのは間違いありません) メンテナンスなどを考えたらもう少し分かりやすい コードを書いたほうがいいでしょう でもって問題はここ >printf("%c",iro[atesase[i]][0]); #1さんが言われているようにマルチバイトに対応してません 1キャラ持ってくるだけですので本来得たい漢字になりません それが合成されるんで「菌数」のような文字になるわけです (文字列は都度変わっているはずです) #1さん書かれてる様に printf("%s",iro[atesase[i]]); で動くはずです
- himajin100000
- ベストアンサー率54% (1660/3060)
>atesase[]は、定義しただけで、何が入っているかわからない状態です。 やべ、気付かなかったorz
- asuncion
- ベストアンサー率33% (2127/6289)
>char atesase[4]; atesase[]は、定義しただけで、何が入っているかわからない状態です。 それを、 >if(atesase[j]==x) 比較に使うのはまずいです。
お礼
>atesase[]は、定義しただけで、何が入っているかわからない状態です。 for(j=0;j<i;j++) { if(atesase[j]==x) { break; } } }while(j<i); atesase[i]=x; この処理により、iが0の時は比較が飛ばされますしiが1以上ならば、 atesaseの中にランダム値が入力されるのでいいのではないでしょうか? No1さんが指摘してくださっているようにatesaseはint型にする必要が あると思いましたが…
- himajin100000
- ベストアンサー率54% (1660/3060)
#include<stdio.h> #include<stdlib.h> #include<time.h> int main(void) { char *iro[8]={"白","黒","赤","青","黄","緑","橙","茶"}; int x,i,j; int atesase[4]; /* intに変更 */ srand(time(NULL)); /*重複をなくすための処理*/ for(i=0;i<4;i++) { do{ x=rand()%8; for(j=0;j<i;j++) { if(atesase[j]==x) { break; } } }while(j<i); atesase[i]=x; } /*表示させるための処理*/ for(i=0;i<4;i++) { printf("%s",iro[atesase[i]]); /* 別に一文字だけ取ってくる必要はないかと[0]を消して%sにしてみた */ /* 俺はC/C++に詳しくないんですが、マルチバイトの文字を含む文字列を入れたchar配列の1番目 ってそれらまとめて持ってきますかね?不安だったんでこう書いたんですが。 一応俺の環境ではこの修正後のコードとVC++ 2008 on Windows XP SP3で期待通りの結果が出ているように思います */ } return 0; }
お礼
回答ありがとうございます。 確かに、atesase[]はint型でしたね。 >マルチバイトの文字を含む文字列を入れたchar配列の1番目 ってそれらまとめて持ってきますかね? 私も初心者であり詳しいことはわからないのですが、とりあえずは 私の環境である「Borland C++ Compiler 5.5」でも正常に動きました。ありがとうございます。
お礼
>判断が走る どういう意味なのでしょうか?お手数ですがよろしくお願いします。 >メンテナンスなどを考えたらもう少し分かりやすいコードを書いたほうがいいでしょう 初心者で独学なもので分かりやすいコードとにくいコードの違いが まだよくわかりません。今後できるようになっていきたいと思います。