都道府県穴埋めゲーム

#include <iostream.h>
main(){

char color_r[12], color_g[3], color_b[3];

sprintf(color_b, "%d", 123);
sprintf(color_g, "%d", 456);
sprintf(color_r, "%d", 789);

strcat(color_r,",");
strcat(color_r,color_g);
strcat(color_r,",");
strcat(color_r,color_b);

cout << color_r;
printf("\n%s",color_r[11]);

}

結果は

789,456,123
(null)

問題ない。


でも、Winプログラムだと問題がある。

#include <windows.h>
#include <iostream.h>
。。。
 case WM_PAINT:
  hdc = BeginPaint(hWnd, &ps);

  char color_r[12], color_g[3], color_b[3];

  sprintf(color_b, "%d", 123);
  sprintf(color_g, "%d", 456);
  sprintf(color_r, "%d", 789);

  strcat(color_r,",");
  strcat(color_r,color_g);
  strcat(color_r,",");
  strcat(color_r,color_b);

  TextOut(hdc,10,10,color_r,strlen(color_r));
  EndPaint(hWnd, &ps);
 break;

結果は、実行時エラーです。
えらーだけど、TextOut( ) での表示が
789,456,123456
となっているのは見れる。
456 というのがくっく。
これが問題。

char color_r[12], color_g[4], color_b[4];

として \0 の領域を用意してやれば問題は起こらないけど、
[4] にしたとして、\0 がどのように作用しているのかが
分かりません。
[3] のエラーは
 strcat(color_r,color_b);
の次に
 strcat(color_r,"\0");
を書けばいいような気がしてやってみたけど、
結果は変わらず、実行時エラー。

やっていることは GetPixel( ) の3色分離だけど、
配列の \0 をケチって宣言すると、
R,G,B が、R,G,BG となってしまうことが分かったけど
どうして R,G,BG になるのかを知りたいです。

A 回答 (3件)

printf("color_r=%x color_g=%x color_b=%x\n",color_r,color_g,color_b);


として実行してみて下さい。それぞれの配列のアドレス(先頭アドレス)が
示されます。そこから指定したバイト分がその変数の領域です。
ちなみに、この配置は処理系に依存します。
    • good
    • 0
この回答へのお礼

ありがとうございます。
printf("%x") で調べて、疑問は解決しました。

お礼日時:2001/12/28 00:55

#1の方の回答にあるように偶然です。


Cの処理系によっては、奇数バイト配列のメモリ上のバウンダリをWORDで扱えるように調整するものもあるので、たまたまそうなったとしかいいようがありません。

またstrcatは文字列連結を行う関数ですが、Cでいう文字列とは「終端文字がnullである」です。
strcatは連結する文字列のnullまでを検索してそれをtarget変数に連結します。
つまり、[3]で宣言した変数にはnullが存在しないため、最悪暴走します。

このことからも、Cで文字列を取扱う場合は必ずnullが入るように1バイト追加して変数宣言するのが常識です。
    • good
    • 0

R,G,BG になるのは、たまたまそうなったと考えてください。



strcatは、文字列を扱う関数なので、
char color_r[12], color_g[3], color_b[3];
で宣言した場合、\0を入れていないため、宣言していない領域外までくっつけてしまうことになります。
この場合、color_g[3]の次が偶然\0だったと思ってください。
color_b[3]の次に、color_g[3]の領域が取られていたと思ってください。

ですので、コンパイルし直すと、違う結果が出てくるかもしれないです。

この回答への補足

必ず R,G,BG になるわけではないけど、
取得する色によって結果が違うんだけど、
R,G,BG になることが多いんです。

Winプログラムの方で、領域外までくっつけてしまうことになるのは
どの行ですか?
それはコンソールの方では起こらないんですか?
コンソールの方で
printf("\n%s",color_r[11]); が \0 になったのは
偶然ですか?

補足日時:2001/12/27 02:07
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報