質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

583閲覧

C言語 区切り分割ができない。

A_.1

総合スコア6

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2021/09/02 00:57

前提・実現したいこと

私は、文字を入力して 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です

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2021/09/02 01:10

Visual Studio 2019 では再現しません。"abcd"が出力されます。 ※ 一か所変更: static char str[] = "a,b,c,d"; // char* -> char[]
dodox86

2021/09/02 02:17

とりあえずback spaceは関係無さそうなコードですが、その前の段階で要望通りの動きにならないので困っているという話でしょうか。 > wsprintf(b,"%s%s",b,token); で文字列トークンを繋げていこうというつもりなのかもしれませんが、ちょっと使い方が乱暴ですね。
A_.1

2021/09/02 02:47

まず、私はキーボードイベントを使って、入力した値を文字列に代入し、それを表示させています。そして、その数だけint型の変数の値をあげます。 back spaceをおすと文字を削除させるために、strtokを使おうと思い、 まず文字列に値を入れるとき、"," を間にいれて後でstrtokでint型の変数の分だけ分割と連結をして削除しようと思いましたが、少し乱暴ですか? もっと効率が良い方法があるなら教えてほしいです。 説明下手なので、わからなかったらすいません。
dodox86

2021/09/02 03:07

乱暴、と書いたのは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の方でうまく処理をしてくれているのだと思います。一般的には文字列を"連結する"ことを意識しつつ、そのようなコードを書きます。まぁ、要望通りに動作しているのでとりあえず良いのではないでしょうか。
episteme

2021/09/02 03:21 編集

wsprintf(b+strlen(b), "%s", token); ではいかがかと。 てか strcat(b, token); でよかろーと。
A_.1

2021/09/02 03:29

ありがとうございます。 その方法でもできました。 少し内容はわかりませんが、 b[b]にtokenをいれてるのでしょうか?
episteme

2021/09/02 03:59

b+strlen(b) : 先頭位置がbで、それに現在のbの長さを足したとこ。 つまり文字列bの末尾に書き込むことになる。
guest

回答1

0

ベストアンサー

回答になるかどうかわからないけど、間違いを1つ。

static char *str = "a,b,c,d";

このstrの指し先は、定数値となるため、書き換えはできません(できないことになっている)
いったん、変数配列にコピーしてからやってみては

投稿2021/09/02 01:13

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

A_.1

2021/09/02 02:28

回答遅れてすいません。 static char *strをstatic char str[]にしたらできました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問