前提・実現したいこと
私は、文字を入力して back space を入力したら文字を削除しようと思っています。
なので、back space を入力したら文字列の未尾を削除しようと思い、strtokで実現しようと思いましたが、コンパイルはできるものの文字が表示されず、すぐウィンドウズが閉じてしまいます。
これは、","で分割し、それをwsprintf()でbに入れてます。そうすると、"a,b,c,d"が"abcd"に
なるのではと思いましたが、文字が表示されず、すぐに閉じてしまいます。
該当のソースコード
C
1#include <windows.h> 2LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) { 3 PAINTSTRUCT ps; 4 static char *str = "a,b,c,d"; 5 static char *token; 6 static char b[300]; 7 LPCTSTR a; 8 HDC hdc; 9 switch (msg) { 10 case WM_DESTROY: 11 PostQuitMessage(0); 12 return 0; 13 case WM_PAINT: 14 hdc = BeginPaint(hwnd,&ps); 15 token = strtok(str,","); 16 wsprintf(b,"%s%s",b,token); 17 token = strtok(NULL,","); 18 wsprintf(b,"%s%s",b,token); 19 token = strtok(NULL,","); 20 wsprintf(b,"%s%s",b,token); 21 token = strtok(NULL,","); 22 wsprintf(b,"%s%s",b,token); 23 a = b; 24 TextOut(hdc,0,0,b,lstrlen(b)); 25 EndPaint(hwnd,&ps); 26 return 0; 27 28 } 29 return DefWindowProc(hwnd , msg , wp , lp); 30} 31 32int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance , 33 PSTR lpCmdLine , int nCmdShow ) { 34 HWND hwnd; 35 MSG msg; 36 WNDCLASS winc; 37 38 winc.style = CS_HREDRAW | CS_VREDRAW; 39 winc.lpfnWndProc = WndProc; 40 winc.cbClsExtra = winc.cbWndExtra = 0; 41 winc.hInstance = hInstance; 42 winc.hIcon = LoadIcon(NULL , IDI_APPLICATION); 43 winc.hCursor = LoadCursor(NULL , IDC_ARROW); 44 winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 45 winc.lpszMenuName = NULL; 46 winc.lpszClassName = TEXT("KITTY"); 47 48 if (!RegisterClass(&winc)) return -1; 49 50 hwnd = CreateWindow( 51 TEXT("KITTY") , TEXT("Kitty on your lap") , 52 WS_OVERLAPPEDWINDOW | WS_VISIBLE , 53 CW_USEDEFAULT , CW_USEDEFAULT , 54 CW_USEDEFAULT , CW_USEDEFAULT , 55 NULL , NULL , hInstance , NULL 56 ); 57 58 if (hwnd == NULL) return -1; 59 60 while(GetMessage(&msg , NULL , 0 , 0)) { 61 DispatchMessage(&msg); 62 } 63 return msg.wParam; 64} 65
補足情報(FW/ツールのバージョンなど)
MinGW-win32を使っております。
コンパイル方法は、gcc -mwindows filename.cです
Visual Studio 2019 では再現しません。"abcd"が出力されます。
※ 一か所変更: static char str[] = "a,b,c,d"; // char* -> char[]
とりあえずback spaceは関係無さそうなコードですが、その前の段階で要望通りの動きにならないので困っているという話でしょうか。
> wsprintf(b,"%s%s",b,token);
で文字列トークンを繋げていこうというつもりなのかもしれませんが、ちょっと使い方が乱暴ですね。
まず、私はキーボードイベントを使って、入力した値を文字列に代入し、それを表示させています。そして、その数だけint型の変数の値をあげます。
back spaceをおすと文字を削除させるために、strtokを使おうと思い、
まず文字列に値を入れるとき、"," を間にいれて後でstrtokでint型の変数の分だけ分割と連結をして削除しようと思いましたが、少し乱暴ですか?
もっと効率が良い方法があるなら教えてほしいです。
説明下手なので、わからなかったらすいません。
乱暴、と書いたのはwsprintfという関数の使い方のお話です。wsprintfはWindows APIで提供される関数ですが、
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-wsprintfa
wsprintf(b,"%s%s",b,token);とコードに書いた場合、第3引数でbを指定しているのでbを
参照しつつ同じbと言う文字列バッファに上書きしているかたちです。
上記の公式のリファレンスにはそのような使い方が許されているとは書いていないので、APIの方でうまく処理をしてくれているのだと思います。一般的には文字列を"連結する"ことを意識しつつ、そのようなコードを書きます。まぁ、要望通りに動作しているのでとりあえず良いのではないでしょうか。
wsprintf(b+strlen(b), "%s", token); ではいかがかと。
てか strcat(b, token); でよかろーと。
ありがとうございます。
その方法でもできました。
少し内容はわかりませんが、
b[b]にtokenをいれてるのでしょうか?
b+strlen(b) : 先頭位置がbで、それに現在のbの長さを足したとこ。
つまり文字列bの末尾に書き込むことになる。
回答1件
あなたの回答
tips
プレビュー