• 締切済み

case で宣言コンパイルエラー

 switch (msg){  case WM_LBUTTONDOWN:   char *p = new char[1000];   wsprintf(p, "%d" , i);   MessageBox(hWnd , p , "" , MB_OK);   delete[] p;  break; がエラーで  switch (msg){  case WM_LBUTTONDOWN:   char *p;   p = new char[1000];   wsprintf(p, "%d" , i);   MessageBox(hWnd , p , "" , MB_OK);   delete[] p;  break; と  switch (msg){  case WM_KEYDOWN:   if( wParam == VK_RETURN ){    char *p = new char[1000];    wsprintf(p, "%d" , i);    MessageBox(hWnd , p , "" , MB_OK);    delete[] p;   }  break; ならエラーじゃなかったんだけど、理由がよく分かりません。 case のすぐ下で宣言と同時に値を代入してはいけないんですか?

  • A__
  • お礼率59% (194/328)

みんなの回答

  • haporun
  • ベストアンサー率40% (230/562)
回答No.4

new char[1000] は (char*)malloc(1000) と同値なので、構文上の間違いはありません。 とにかく、この文をコピーしただけではエラーは起こりえないので、これ以前のコードを補足するか、エラーのあった行を自分で調べるかしてください。 ちなみにifは新しいスコープを作らないので、ブロックであってもその1つ上のスコープをもっています。 例を挙げると、 if(hoge){ int x; } if(hoge){ int x; //すでに宣言されているのでエラー } while(hoge){ int y; } while(hoge){ int y; //違うスコープなのでエラーでない } この辺がおそらく原因だと思うのですが・・・。 最近のCは関数のいちばん上でなくとも変数宣言できますが、関数内での変数名の管理上、やはり変数は関数のいちばん上で宣言した方がわかりやすいです。

A__
質問者

補足

ありがとうございます。 でも、やってみると if(hoge){ int x; } if(hoge){ int x; //エラーにならず } コンパイルできました。

  • tdlemon
  • ベストアンサー率37% (3/8)
回答No.3

char *p = newchar[1000]; は明らかにおかしいです! pはポインタ変数で宣言されてるので &newchar[1000]のように 変数のアドレス値を代入しなければいけません。 値を入れようとするとエラーが出ます。 なので、エラーが出ないといってる2つの例のうち 下のほうはタイプミスでは? タイプミスがどうか調べてみてください。

A__
質問者

お礼

ありがとうございます。 でも、newchar でなく、new char です。

  • hyde_la
  • ベストアンサー率50% (1/2)
回答No.2

case は単にラベルで、ラベル以降、同じスコープに 初期化構文を書けなくなるのが仕様です。 switchの場合は、 switch( value ){ int i = 0; char* p = NULL; case X: とすればOKです。 あとブロックを作るか。

  • haporun
  • ベストアンサー率40% (230/562)
回答No.1

VC++を使っているなら、表示されたエラーメッセージをダブルクリックすると、問題となっている文を指摘してくれます。 そうでなくても、コンパイルエラーは何行目がエラーが指摘してくれるので、どこがエラーになっているかは少なくとも自分で確かめたほうがいいでしょう。 少なくとも、この部分だけでは、switch内で変数を宣言し、初期化したことによるエラーはありえません。

関連するQ&A

  • wsprintf( ) でポインタに代入

    wsprintf(p, "%d" , i); を書いたせいで、i の値が変わります。 wsprintf(p, "%d" , i); によってどんなことが起こっているのか詳しく知りたいです。 ポインタのことがまだよく分かってないんです。 #include <windows.h> LPCSTR szStr = "\n char c[255];\n char *p = \"\\0\";\n int i = 12345;\n\n switch (msg){\n case WM_LBUTTONDOWN:\n  wsprintf(c, \"%d\" , i);\n  wsprintf(p, \"%d\" , i);\n  MessageBox(hWnd , c , \"\" , MB_OK);\n break;"; LRESULT CALLBACK WndProc(HWND , UINT , WPARAM , LPARAM); int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE , LPSTR , int){ 省略 return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wParam , LPARAM lParam){ HDC hDC; PAINTSTRUCT ps; RECT rt; char c[255]; char *p = "\0"; int i = 12345; switch (msg){ case WM_LBUTTONDOWN: wsprintf(c, "%d" , i); wsprintf(p, "%d" , i); MessageBox(hWnd , c , "" , MB_OK); break; case WM_PAINT: GetClientRect(hWnd, &rt); hDC = BeginPaint(hWnd, &ps); DrawText(hDC, szStr, lstrlen(szStr), &rt, DT_WORDBREAK); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return(DefWindowProc(hWnd , msg , wParam , lParam)); } return (0L); }

  • ドロップで起動するけどパスは?

    ファイルをEXEにドロップして起動させます。 ドロップしたファイルのパスを GetCommandLine( ) から 取り出すために、" の位置を調べます。 "EXEのパス" ドロップファイルのパス となっているから、2番目の " の位置を調べました。 でも、for でのループが1回で終わってしまいます。 おかしいところを教えてください。 LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) {  char *p = GetCommandLine();  char str[200];  switch(msg){  case WM_CREATE:   int i;   for(i = 1; p[i] == '"'; i++);{    wsprintf(str, "%d", p[i]);    MessageBox(hWnd, chStr, "", MB_OK);   }   wsprintf(chStr, "%d", i);   MessageBox(hWnd, str, "", MB_OK); //結果は1   wsprintf(chStr, "%#x", p[0]);   MessageBox(hWnd, str, "1文字目", MB_OK); //結果は34   wsprintf(chStr, "%#x", p[1]);   MessageBox(hWnd, str, "2文字目", MB_OK); //結果は67   wsprintf(chStr, "%#x", p[2]);   MessageBox(hWnd, str, "3文字目", MB_OK); //結果は58

  • 2重Func禁止。クリセク。セマフォ。

    MyFunc( ) の実行中は WM_LBUTTONDOWN を無視されるように しようと思いました。 LRESULT CALLBACK WndProc(… {  static bool b = TRUE;  switch(msg){  case WM_LBUTTONDOWN:   if(b){    b = FALSE;    MyFunc( ); //  MessageBox(hWnd, "", "", MB_OK);    b = TRUE;   }  break; でもこれでは、例えば MyFunc( ) が実行中に3回クリックすると その後に MyFunc( ) は3回実行されてしまいます。 MessageBox( ) を使えばうまくいくけと、それは使いたくありません。 できるだけ簡単なソースで、 MyFunc( ) の実行中のクリックで、後で MyFunc( ) が 実行されないようにするにはどこを直したらいいですか?

  • 子ウインドウの作成と破棄について

    CALLBACK のみを書きました。 メインウインドウを破棄したら 子ウインドウも破棄したいのですが、 うまく出来ません。 どうすればよろしいでしょうか? よろしくお願いします。 #include<windows.h> #include"ChildWindow.h" char MainWindowClassName[]="mainwindow"; LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { static HWND childWnd; switch(message) { case WM_ACTIVATEAPP: childWnd=Child_CreateWindow(hWnd,message,wParam,lParam); break; case WM_DESTROY: DestroyWindow(childWnd); PostQuitMessage(0); break; default: return DefWindowProc(hWnd,message,wParam,lParam); } } ///////////////////////////////////////////// #include<windows.h> char ChildWindowClassName[]="childwindow"; LRESULT CALLBACK ChildProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_LBUTTONDOWN: MessageBox(NULL,"","",MB_OK); break; default: return DefWindowProc(hWnd,message,wParam,lParam); } } ATOM Child_RegistWindow(HINSTANCE hInstance){} HWND Child_InitInstance(HWND hParentWnd,HINSTANCE hInst,int CmdShow){} HWND Child_CreateWindow(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { int CmdShow=1; Child_RegistWindow(NULL); HWND ChildWnd=Child_InitInstance(hWnd,NULL,CmdShow); MSG msg; while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return ChildWnd; }

  • C言語・Windows RECTが渡せない

    C言語のWindowsプログラムで、左クリック後に四角形の描画をしたいのですがうまくいきません。 WM_LBUTTONDOWNイベントで定義したRECT構造体を、別の関数に渡しRectangleで描画したいのですが、その関数内でRECTの値を調べるととんでもない値になっています。 何度やってもどうして値がおかしくなるのかわかりません。 WM_LBUTTONDOWNもWM_PAINTも正常に反応していると思います。 どうか知恵をお貸しくださいm(_ _)m 以下ソースコードのメッセージ処理部分です。 ウィンドウ生成のひな型はサイトの物を丸写しし、正常に動作することを確認しています。 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rcPos; switch (msg){ case WM_LBUTTONDOWN: rcPos.top =0; rcPos.left =0; rcPos.bottom =100; rcPos.right =100; InvalidateRect(hWnd, &rcPos, FALSE); break; //ウィンドウの描画 case WM_PAINT: hdc = BeginPaint(hWnd, &ps); DrawGr(hWnd, hdc, &rcPos); EndPaint(hWnd, &ps); break; //ウィンドウの削除 case WM_DESTROY: PostQuitMessage(0); break; default: return(DefWindowProc(hWnd, msg, wParam, lParam)); } return (0L); } //描画 int DrawGr(HWND hWnd, HDC hdc, RECT *rcPos) { int i; HBRUSH hBrush, hOldBrush; char *str_org = "rc.top=%d rc.left=%d rc.bottom=%d rc.right=%d"; char strx[256]; //四角形 hBrush = CreateSolidBrush(RGB(100, 100, 255)); hOldBrush = (HBRUSH)SelectObject(hdc, hBrush); //デバッグ用 wsprintf((LPSTR)strx, (LPCSTR)str_org, rcPos->top, rcPos->left, rcPos->bottom, rcPos->right); MessageBox(hWnd, (LPCSTR)strx, (LPCSTR)"終了確認", MB_OKCANCEL | MB_ICONQUESTION); Rectangle(hdc, rcPos->left, rcPos->top, rcPos->right, rcPos->bottom); SelectObject(hdc, hOldBrush); DeleteObject(hBrush); return 0; }

  • win32apiでの動画出力

    win32apiとopenCVを使った動画出力プログラムを作りたいのですが, フリーズしてしまいます. 詳しい方,力を貸してください. 以下にプログラムを載せます. LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { int x, y; int id; int c; char* szWndName = "camera capture"; CvCapture* capture; // IplImage* img; switch (msg) { case WM_CREATE: hDC = GetDC( hWnd ); return DefWindowProc(hWnd, msg, wParam, lParam); case WM_COMMAND: switch(LOWORD(wParam)){ case IDM_END: SendMessage(hWnd, WM_CLOSE, 0, 0L); break; case IDM_USB: capture = cvCaptureFromCAM(0); if(capture == NULL){ MessageBox(hWnd, (LPCTSTR)TEXT("Not camera"), (LPCTSTR)TEXT("Test"), MB_OK); return -1; } while(1){ img = cvQueryFrame(capture); bmpData = (LPDWORD)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, img->width * img->height * 4); iplTobmp(img, bmpInfo, bmpData); StretchDIBits( hDC, 0, 0, img->width, img->height, 0, 0, img->width, img->height, bmpData, &bmpInfo, DIB_RGB_COLORS, SRCCOPY); } ReleaseDC(hWnd, hDC); cvReleaseCapture(&capture); return 0; break; } break; case WM_LBUTTONDOWN: // マウスカーソルが移動したときに送られてくる // 移動先の座標を取得 x = LOWORD( lParam ); y = HIWORD( lParam ); // 座標をテキストファイルに書き込む _ftprintf( g_fp, _T("(%d %d)\n"), x, y ); return 0; case WM_CLOSE: id = MessageBox(hWnd, TEXT("Close?"), TEXT("Close"), MB_OKCANCEL | MB_ICONQUESTION); if(id == IDOK) DestroyWindow(hWnd); return (0L); case WM_DESTROY: PostQuitMessage(0); break; default: return(DefWindowProc(hWnd, msg, wParam, lParam)); } return (0L); }

  • CTreeCtrlのCreate関数でエラーになります。

    Visual C++ .NET Win32 プロジェクト で、アプリケーションを作成しようと思っています。 #include<afxwin.h> #include<afxcmn.h> // マルチスレッド CTreeCtrl *m_TreeCtrl; LRESULT CALLBACK int WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_LBUTTONDOWN: m_TreeCtrl=new CTreeCtrl; m_TreeCtrl->Create(WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_BORDER | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES | TVS_DISABLEDRAGDROP, CRect(10, 10, 300, 100), CWnd::FromHandle(hWnd), 10000); break; case WM_CREATE: break; case WM_DESTROY: PostQuitMessage(0); break; case WM_PAINT: HDC hDC; PAINTSTRUCT Paint; hDC=BeginPaint(hWnd,&Paint); EndPaint(hWnd,&Paint); } return DefWindowProc(hWnd,message,wParam,lParam); } ・・・ と記述すると、エラーになります。 解決方法を教えてください。

  • 自作関数で元の値を変更したい

    ポインタとかが分からないので教えてください。 元のプロセスで  case WM_KEYDOWN:   MyFunc(hWnd);   if(!hWnd)MessageBox(NULL, "成功", "", MB_OK);   else MessageBox(NULL, "エラー", "", MB_OK);  break; 元のプロセスの自作関数で void MyFunc(HWND wnd){  SetWindowText(wnd, "てすと");//これはちゃんとできた。  wnd = NULL;//ここが失敗で、この関数を抜けるまでしか効果がない。 } これで MessageBox(NULL, "エラー", "", MB_OK); が実行されてしまいました。

  • 結果待ちの関数を強制終了

    結果待ちで処理が止まっている場合、その結果待ちの部分を 結果はどうでもいいから、もう結果を待たないというふうに させる方法を教えてください。 例えば、MessageBox関数を使った場合、5秒以内に クリックさせなかったら、MessageBoxの返り値を適当に決める 方法を教えてください。 たぶんそれをすると、メッセAとメッセBは別プロシージャとか 別関数に分かれて書くことになると思うけど、それでもいいんです。 例えば、まず最初に、case ONE;が実行させる場合です。 case ONE;  SetTimer(hWnd, 1234, 5000, NULL);  PostMessage(hWnd, TWO, 0, 0);  break; case TWO;  MessageBox(hWnd, "クリックしてください", "メッセA", MB_OK);  //クリックされるまでここで処理が止まる。  MessageBox(hWnd, "結果は~でした。", "メッセB", MB_OK);  break; case WM_TIMER:  KillTimer(hWnd, 1234);  //メッセAを取り消すような処理をしてメッセBを表示させたい。  break;

  • TextOut( ) が動かない

    LRESULT CALLBACK WndProc( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){ PAINTSTRUCT ps; HDC hdc; switch(msg){ case WM_KEYDOWN:  if( wParam == VK_ESCAPE ){   hdc = BeginPaint(hWnd, &ps);   TextOut(hdc,0,0,str,strlen(str));   EndPaint(hWnd, &ps);  }  break; case WM_PAINT:  break; エスケープキーで文字表示をやりたいけど TextOut( ) が動作していないみたいでした。 switch(msg){ case WM_KEYDOWN:  if( wParam == VK_ESCAPE ){   hdc = BeginPaint(hWnd, &ps);   TextOut(hdc,0,0,str,strlen(str));   EndPaint(hWnd, &ps);  }  break; case WM_PAINT:  hdc = BeginPaint(hWnd, &ps);  TextOut(hdc,0,0,str,strlen(str));  EndPaint(hWnd, &ps);  break; とすると、常に文字が表示されたから、やっぱり case WM_KEYDOWN: の中の TextOut( ) が 動作していないんだと思いました。 TextOut( ) は case WM_PAINT: からのつながりが ある場合でないと実行されないんですか? ソースのおかしいところがあったら教えてください。