OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

\0 sprintf( ) strcat( )

  • 暇なときにでも
  • 質問No.191140
  • 閲覧数367
  • ありがとう数4
  • 気になる数0
  • 回答数3
  • コメント数0

お礼率 59% (194/328)

#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
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

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

  • 回答No.2
レベル13

ベストアンサー率 24% (357/1463)

printf("color_r=%x color_g=%x color_b=%x\n",color_r,color_g,color_b);
として実行してみて下さい。それぞれの配列のアドレス(先頭アドレス)が
示されます。そこから指定したバイト分がその変数の領域です。
ちなみに、この配置は処理系に依存します。
お礼コメント
A__

お礼率 59% (194/328)

ありがとうございます。
printf("%x") で調べて、疑問は解決しました。
投稿日時 - 2001-12-28 00:55:50
-PR-
-PR-

その他の回答 (全2件)

  • 回答No.1
レベル8

ベストアンサー率 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]の次に、col ...続きを読む
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]の領域が取られていたと思ってください。

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

お礼率 59% (194/328)

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

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


  • 回答No.3
レベル9

ベストアンサー率 53% (41/76)

#1の方の回答にあるように偶然です。 Cの処理系によっては、奇数バイト配列のメモリ上のバウンダリをWORDで扱えるように調整するものもあるので、たまたまそうなったとしかいいようがありません。 またstrcatは文字列連結を行う関数ですが、Cでいう文字列とは「終端文字がnullである」です。 strcatは連結する文字列のnullまでを検索してそれをtarget変数に連結します。 つまり、[3] ...続きを読む
#1の方の回答にあるように偶然です。
Cの処理系によっては、奇数バイト配列のメモリ上のバウンダリをWORDで扱えるように調整するものもあるので、たまたまそうなったとしかいいようがありません。

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

このことからも、Cで文字列を取扱う場合は必ずnullが入るように1バイト追加して変数宣言するのが常識です。
このQ&Aで解決しましたか?
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ