VC2005 C++で
Q1:PID表示
HWND thwnd;
DWORD tdword;
LPDWORD tlpd;
thwnd=FindWindow(NULL,メモ);
tdword=GetWindowThreadProcessId(thwnd,tlpd);
として、「メモ」というタイトルのソフトのPIDを取得しているつもりです。
tlpd にPIDが入ってるはずですよね?
これを、画面に表示しようと
case WM_PAINT:
hDC = BeginPaint(hWnd,&ps);
TextOut( hDC, 10, 10, (char)tlpd, (int)strlen(tlpd) );
EndPaint(hWnd,&ps);
return 0;
としてみましたが、コンパイルできません。
どのようにすればいいのでしょうか?
Q2:文字列結合
char str1[] = CDM:;
char str2[] = He is microsoft.;
char str3[] = str1+str2;
では、str3にCDM:he is microsoft.
と入りません。
「'+' : ポインタにポインタを加えようとしました」
などとでてしまいます
よろしくお願いします
Q1
どんなコンパイルエラーがでたか、きちんと情報を提示してください。
GetWindowThreadProcessIdの使い方が違います。変数の実体が確保されてません。
その上で、ウィンドウハンドルがちゃんと取れる保証はありません。
実行時のエラーチェックもしてください。(入っている「はず」なんてありえない…)
strlenの使い方も間違っています。
TextOutの用法もです。
# 本質的にキャストは無理やりコンパイラを黙らせようとする指示であって、
# 形式を取り繕っただけでは、期待通りの動作にならないことも多々あります。
# キャストを多用するコードには問題が内在する可能性が高いです。
C言語の理解が足りていないことが見て取れます。ポインタから勉強してください。
Q2
・C言語の文字列に対する理解も足りていません。
・C言語では、+による文字列の結合などはできません。文字列操作用の標準関数を使って
ください。
(まともなC言語の入門書には載ってるはずですので、勉強しながら探してみてくださ
い)
# C++で書くなら、C言語互換のchar配列やstrlenなどはそもそも使わずに
# std::stringを使った方がよい気はしますが。
こうすればいいのでは?
やりたいことが違ったらごめんなさい。
HWND thwnd;
DWORD tdword;
thwnd=FindWindow(NULL,メモ);
tdword=GetWindowThreadProcessId(thwnd,NULL);
char str[256];
wsprintf(str,Id = %d,tdword);
case WM_PAINT:
hDC = BeginPaint(hWnd,&ps);
TextOut( hDC, 10, 10, str, strlen(str) );
EndPaint(hWnd,&ps);
return 0;
文字列結合は
char str1[] = CDM:;
char str2[] = He is microsoft.;
char str3[] = str1+str2;//ここがいけない
char str1[] = CDM:;
char str2[] = He is microsoft.;
strcat(str1,str2);//str1にCOM:He is microsoft.が入る
もしくは
char str3[256];
wsprintf(str3,%s%s,str1,str2);//str3にCOM:He is microsoft.が入る
>char str1[] = CDM:;
>char str2[] = He is microsoft.;
>strcat(str1,str2);//str1にCOM:He is microsoft.が入る
str1の領域足りてないぞ
>char str1[] = CDM:;
>char str2[] = He is microsoft.;
>char str3[] = str1+str2;
文字列指定して初期化するならこんな風にサイズを指定したほうがいいですね。
あと、'\0'はつけたほうがいいです。
char str1[30] = CDM:\0;
char str2[30] = He is microsoft.\0;
char str3[256];// = str1+str2;
横やり失礼します。
>あと、'\0'はつけたほうがいいです。
>char str1[30] = CDM:\0;
>char str2[30] = He is microsoft.\0;
なぜ \0 をつけた方がいいのでしょうか?
>なぜ \0 をつけた方がいいのでしょうか?
今回の場合は初期化なのでいいのかもしれませんが、strcpy,strcpy,strlen等の
関数は先頭から最初の'\0'まで対象の文字列として扱います。
ですから、
「strcpy,strcpy,strlen等の関数を扱う時は'\0'をつける用にしたほうはいい。」
というだけです。
abc は {'a','b','c','\0'} なのにわざわざ \0 を手書きする必要は無いと思うが
>abc は {'a','b','c','\0'} なのにわざわざ \0 を手書きする必要は無いと思うが
失礼しました。
初期化のときは確かに必要なかったと思います。
>「strcpy,strcpy,strlen等の関数を扱う時は'\0'をつける用にしたほうはいい。」
>というだけです。
'\0'をつける用にしたほうはいいではなくて'\0'を付けなければならないですね。
私が疑問に思ったのは tetrapod さんが仰っている通り、なぜ文字列リテラルにわざわ
ざ \0 を明記するのか?
という事です。
初期化以外の場所に表れても、abcは const char[4] 型 (ただし、char * に代入できるという
特殊ルールあり)で、内容が [0] = 'a'、[1] = 'b'、 [2] = 'c'、 [3] = '\0'、な配列として
扱われます。
で、abc\0だと、[0] = 'a'、[1] = 'b'、[2] = 'c'、[3] = '\0'、[4] = '\0'な
const char[5]型。
末尾の連続する'\0'をひとつにまとめるといったことはありませんので、'\0'で終わっていることを
明示的に表す、という目的だとしてもいかがなものかと。
そういえば化けるんだった……
\は、「\」または「¥」と読み換えてください。
>初期化以外の場所に表れても
初期化以外でも、末尾は必ず'\0'になるんですか。
初期化以外だと何が入っているかわからないので、
memset等の関数で'\0'で埋めるか、末尾を ='\0'に設定しないといけないと思って
いました。