課題研究でゲームを作っています
コンパイルはうまくいくんですが
実行した後正常終了してくれません
どこがいけないのでしょうか
#include "DxLib.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
SetGraphMode( 800 , 600 , 32 ) ;
ChangeWindowMode( TRUE ) ;
int MouseX , MouseY ; //マウス位置
int StringCr , BoxCr ; //文字色
int Maru[ 3 ] , Mx = 145 , My = 350 ; //○ボタン
int Batu[ 3 ] , Bx = 390 , By = My ; //×ボタン
int Play_win; //ゲームウィンドウ
int Chara1; //自キャラ
int Time; //制限時間
int FontHandle; //問題文用フォント
int i=0,j=0,k,l=0,Pf=0; //文字用配列 i:文字数 j:行数 k:バッファ配列用 l:問題文の文字カウント Pfページフラグ
char QBuf[4][35]={"","","",""},Question[200] = {"あいうえおかきくけこさしすせそたちつてと"}; //問題文バッファと問題文
int Ans = 0 , Qnum ; //回答と問題番号
int Bflag=3; //ボタンフラグ 0:○ 1:× 2:無回答
if( DxLib_Init() == -1 ) // DXライブラリ初期化処理
{
return -1; // エラーが起きたら直ちに終了
}
// 描画先を裏画面にする
SetDrawScreen( DX_SCREEN_BACK ) ;
// マウスを表示状態にする
SetMouseDispFlag( TRUE ) ;
// 白色の値を取得
StringCr = GetColor( 255 , 255 , 255 ) ;
// 黒の値を取得
BoxCr = GetColor( 0 , 0 , 0 ) ;
LoadDivGraph( "data/maru.png" , 3 , 3 , 1 , 225 , 225 , Maru ) ;
LoadDivGraph( "data/batu.png" , 3 , 3 , 1 , 225 , 225 , Batu ) ;
Play_win = LoadGraph( "data/play_win.png" ) ;
Chara1 = LoadGraph( "data/chara.png" ) ;
Time = GetNowCount() ;
FontHandle = CreateFontToHandle( NULL , 24 , 0 , DX_FONTTYPE_ANTIALIASING_EDGE) ;
while( GetNowCount() - Time < 600000)
{
//ClearDrawScreen() ;
DrawGraph( 0 , 0 , Play_win , TRUE ) ;
DrawGraph( 600 , 300 , Chara1 , TRUE ) ;
// マウスの位置を取得
GetMousePoint( &MouseX , &MouseY ) ;
DrawBox( 0 , 0 , 200 , 32 , BoxCr , TRUE ) ;
// 座標文字列を描く
DrawFormatString( 0 , 0 , StringCr , "%d" ,MouseX) ;
DrawFormatString( 50 , 0 , StringCr , "%d" ,MouseY) ;
//問題文を表示するところ
if(j < 4){
if(i>=34){
QBuf[j][35] = '\0'; //改行するためにヌル入れる
i=0; //カーソルを最初に戻す
j++; //改行
}
QBuf[j] = Question[[/url];
QBuf[j][i+1] = Question[l+1];
QBuf[j][i+2] = '\0';
}
for(k=0;k<j;k++){
DrawFormatStringToHandle( 150 , 10 + 26 * k , StringCr , FontHandle , "%s" , QBuf[k]) ;
}
if(Question != '\0'){
i+=2;
l+=2;
}
//問題文表示ここまでここまで
//○×ボタン
//○ボタン
if( (MouseX <= Mx + 225 && MouseX >= Mx) && (MouseY <= My + 225 && MouseY >= My) ){
if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 )
{
DrawGraph( Mx , My , Maru[ 2 ] , FALSE ) ;// 押されている
Bflag = 0;
}
else
{
DrawGraph( Mx , My , Maru[ 1 ] , FALSE ) ;// 押されていない
}
}
else{
DrawGraph( Mx , My , Maru[ 0 ] , FALSE ) ;
}
//×ボタン
if( (MouseX <= Bx + 225 && MouseX >= Bx ) && (MouseY <= By + 225 && MouseY >= By) ){
if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 )
{
DrawGraph( Bx , By , Batu[ 2 ] , FALSE ) ;// 押されている
Bflag = 1;
}
else
{
DrawGraph( Bx , By , Batu[ 1 ] , FALSE ) ;// 押されていない
}
}
else{
DrawGraph( Bx , By , Batu[ 0 ] , FALSE ) ;
}
//ボタンここまで
// メッセージ処理
if( ProcessMessage() == -1 )
{
break ; // エラーが起きたらループを抜ける
}
ScreenFlip() ;
if(Bflag != 3) break;
// 一定時間待つ
//WaitTimer( 1000 ) ;
}
StringCr = GetColor( 255 , 255 , 255 ) ;
ScreenFlip() ;
WaitKey() ;
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
正常終了
Re:正常終了
//問題文を表示するところ if(j < 4){ if(i>=34){ QBuf[j][35] = '\0'; // *1* i=0; //カーソルを最初に戻す j++; //改行 } QBuf[j] = Question[[/url]; // *2* QBuf[j][i+1] = Question[l+1]; QBuf[j][i+2] = '\0'; }
*1*
j=3, i=34 のとき、
QBuf[3][35] = '\0';
は、配列 QBuf の領域外への書き込みが発生します。
*2*
の3行も、配列 QBuf の領域外への書き込みが発生します。
判り易いところでは、前のif文で、jがインクリメントされて4になれば
QBuf[4][0]、QBuf[4][1]、QBuf[4][2] への書き込みが発生します。
ほかに、j=3,i>=33でも領域外への書き込みが発生します。
Re:正常終了
自分がやりたいことは先にあげたソースの中には入ってないのですが
外部ファイルから文字列を読み込んで表示するものです。
外部ファイルから問題文をQuestionに入れて
そこからQBufに17文字ずつ入れていく
QBuf[0]にはQuestionの1~17文字まで
QBuf[1]にはQuestionの18~34文字まで
QBuf[2](3行目)に何も文字が入っていない場合は
3行目以降からは表示しない
文字はすべて2バイト文字です
問題文が24文字の場合は
QBuf[1]の7文字目まで表示
それ以降は表示しない
というものです
自分はプログラム関係は初心者です
しっぽ様の質問に答えられているかどうかすら不安です
外部ファイルから文字列を読み込んで表示するものです。
外部ファイルから問題文をQuestionに入れて
そこからQBufに17文字ずつ入れていく
QBuf[0]にはQuestionの1~17文字まで
QBuf[1]にはQuestionの18~34文字まで
QBuf[2](3行目)に何も文字が入っていない場合は
3行目以降からは表示しない
文字はすべて2バイト文字です
問題文が24文字の場合は
QBuf[1]の7文字目まで表示
それ以降は表示しない
というものです
自分はプログラム関係は初心者です
しっぽ様の質問に答えられているかどうかすら不安です
Re:正常終了
大体判りました。こんなのでどうですか。
注)確保後に繰り返して使用する場合には、QBufとQuestionの領域を
'\0'で埋めておく必要があります。
注)確保後に繰り返して使用する場合には、QBufとQuestionの領域を
'\0'で埋めておく必要があります。
#include <stdio.h> #include <string.h> int main() { int j, k; char QBuf[4][35]={0}; char Question[200] = {"あいうえおかきくけこさしすせそたちつてと"}; //問題文バッファと問題文 // for(j = 0, k = 0; Question[k] && j < 4; ++j, k += 34){ for(j = 0, k = 0; j < 4; ++j, k += 34){ // Question の領域が十分広いから、Question[k] のチェックは不要 memcpy(&QBuf[j][0], &Question[k], 34); } for(j = 0; j < 4; ++j){ printf("%d %s\n", j, &QBuf[j][0]); } return 0; }
Re:正常終了
>一つ目は、今作っているプログラムはDXライブラリを使っていること
DirectX ライブラリを使用したWindowプログラムであるこは、はなから承知してます。
私は DirectX ライブラリを使用したことはありませんが、提示した例を応用することは
それほど難しくはないと思います。DirectX とC言語の標準関数を併用できるか、
もしくは代用の関数がある(Windows だと CopyMemory などがありましたから)かと思います。
>二つ目は、問題文を1文字ずつ表示させるということです
これは、コードのどこの部分ですか?文字列をDrawできるなら、その応用で簡単に
できるかと思います。
あと、パッと見で違和感を覚える部分について、間違えを見つけただけで、他の部分にも
メモリのオーバーランがあるかも知れません。
DirectX ライブラリを使用したWindowプログラムであるこは、はなから承知してます。
私は DirectX ライブラリを使用したことはありませんが、提示した例を応用することは
それほど難しくはないと思います。DirectX とC言語の標準関数を併用できるか、
もしくは代用の関数がある(Windows だと CopyMemory などがありましたから)かと思います。
>二つ目は、問題文を1文字ずつ表示させるということです
これは、コードのどこの部分ですか?文字列をDrawできるなら、その応用で簡単に
できるかと思います。
あと、パッと見で違和感を覚える部分について、間違えを見つけただけで、他の部分にも
メモリのオーバーランがあるかも知れません。