- ベストアンサー
\0 sprintf( ) strcat( )
#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 になるのかを知りたいです。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
printf("color_r=%x color_g=%x color_b=%x\n",color_r,color_g,color_b); として実行してみて下さい。それぞれの配列のアドレス(先頭アドレス)が 示されます。そこから指定したバイト分がその変数の領域です。 ちなみに、この配置は処理系に依存します。
その他の回答 (2)
- MarrowG
- ベストアンサー率53% (41/76)
#1の方の回答にあるように偶然です。 Cの処理系によっては、奇数バイト配列のメモリ上のバウンダリをWORDで扱えるように調整するものもあるので、たまたまそうなったとしかいいようがありません。 またstrcatは文字列連結を行う関数ですが、Cでいう文字列とは「終端文字がnullである」です。 strcatは連結する文字列のnullまでを検索してそれをtarget変数に連結します。 つまり、[3]で宣言した変数にはnullが存在しないため、最悪暴走します。 このことからも、Cで文字列を取扱う場合は必ずnullが入るように1バイト追加して変数宣言するのが常識です。
- yusuke5111
- ベストアンサー率16% (9/55)
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 になったのは 偶然ですか?
お礼
ありがとうございます。 printf("%x") で調べて、疑問は解決しました。