動作が停止してしまいます
Posted: 2012年8月09日(木) 14:30
[1] 質問文
[1.1]メモ帳のテキストを読み込みすることが目標です。
[1.2] mymain.cpp
mymain.h
myhelper.cpp
myhelper.h
メモ帳
1,2,0
めだかボックス第1巻の最初の一言は何か。
世界は平凡か?,世界は平凡か?
0,0,0
char型に0を入れていますが、あまり気にしないでいただけると嬉しいです…
というコードでmymain.cppとmymain.hは自分で書いたコードで、
myhelper.cppとmyhelper.hは解説書についていたコードです。
[1.3]ウィンドウが開いてすぐに、○○○.txtは動作を停止しました、というメッセージがでてしまいます。
[1.4] どうすれば正しくメモ帳が読み込まれるのかがわかりません。
できたら、説明もしていただけると嬉しいです。なにぶん、初めての状況ですので…
[2] 環境
[2.1] OS : Windows
[2.2] コンパイラ名 : VC++ 2008EE DXLib使用
[3] その他
・あまり理解できないかもしれないので、わかりやすく説明、回答していただけると、とてもありがたいです!
とても長いコードですいません。
抜粋がしづらかったので…
[1.1]メモ帳のテキストを読み込みすることが目標です。
[1.2] mymain.cpp
#include "myhelper.h"
#include "mymain.h"
//画像ハンドル
int medaka1;
int kotaewaku[3];
//問題記録変数
Mondai allQ[4];
int g_usedQ_num;
int g_janru = 0;
//問題読み込み関数
int LoadQuestion(char *pfname){
int f = 0; //ファイルハンドル
char buf[1024]; //テキスト一時読み込み一時バッファ
f = FileRead_open(pfname);
if (f==0) return -1; //読み込みエラー
g_usedQ_num = 0;
while( FileRead_eof(f) == 0 ) //終端チェック
{
//一行読み込み
FileRead_gets( buf, 1023, f ) ;
int qn,qk,qm;
sscanf_s(buf, "%d,%d,%d", &qn, &qk, &qm);
Mondai m;
m.Qnum = qn;
m.Qkeishiki = qk;
m.marubatu = qm;
//ZeroMemory(buf, sizeof(buf) * 1024);
char qb[80];
FileRead_gets( qb, 78, f ) ;
memcpy(m.Qbunshou, qb, sizeof(m.Qbunshou));
FileRead_gets( buf, 1023, f ) ;
char Ao[40],At[40];
sscanf_s(buf, "%s,%s", &Ao, &At);
memcpy(m.Answer_one, Ao, sizeof(m.Answer_one));
memcpy(m.Answer_two, At, sizeof(m.Answer_two));
ZeroMemory(buf, sizeof(buf) * 1024);
FileRead_gets( buf, 1023, f ) ;
char a1[20],a2[20],a3[20];
sscanf_s(buf, "%s,%s,%s", &a1, &a2, &a3);
memcpy(m.ans_one, a1, sizeof(m.ans_one));
memcpy(m.ans_two, a2, sizeof(m.ans_two));
memcpy(m.ans_three, a3, sizeof(m.ans_three));
memcpy(allQ[g_usedQ_num].ans_one, m.ans_one, sizeof(allQ[g_usedQ_num].ans_one));
memcpy(allQ[g_usedQ_num].ans_two, m.ans_two, sizeof(allQ[g_usedQ_num].ans_two));
memcpy(allQ[g_usedQ_num].ans_three, m.ans_three, sizeof(allQ[g_usedQ_num].ans_three));
memcpy(allQ[g_usedQ_num].Answer_one, m.Answer_one, sizeof(allQ[g_usedQ_num].Answer_one));
memcpy(allQ[g_usedQ_num].Answer_two, m.Answer_two, sizeof(allQ[g_usedQ_num].Answer_two));
memcpy(allQ[g_usedQ_num].Qbunshou, m.Qbunshou, sizeof(allQ[g_usedQ_num].Qbunshou));
allQ[g_usedQ_num].marubatu = m.marubatu;
allQ[g_usedQ_num].Qkeishiki = m.Qkeishiki;
allQ[g_usedQ_num].Qnum = m.Qnum;
//memcpy(allQ[g_usedQ_num], m, sizeof(allQ[g_usedQ_num]));
g_usedQ_num++;
}
//ファイルを閉じる
FileRead_close( f ) ;
return 0;
}
//メインループ
void MyMain(){
DrawBox( 0,0,640,480,GetColor(255,255,255),TRUE);
//DrawGraph(0,0, medaka1, FALSE);
SetFontSize(32);
ChangeFont("MS Pゴシック");
DrawFormatString(70,170,GetColor(255,0,0),"(Z)物語系 全1問");
DrawFormatString(70,210,GetColor(255,255,0),"(X)人物系 全1問");
DrawFormatString(70,250,GetColor(0,255,0),"(C)スキル系 全1問");
DrawFormatString(70,290,GetColor(0,0,255),"(A)物語(難問)系 全1問");
SetFontSize(40);
DrawFormatString(70,370,GetColor(0,0,0),"ジャンルを選ぶがよい!");
SetFontSize(48);
DrawFormatString(100,50,GetColor(0,0,0),"めだかボックス問題集");
DrawFormatString(100,100,GetColor(0,0,0),"~Quiz Of Medaka~");
int key = GetJoypadInputState( DX_INPUT_KEY_PAD1 );
if( key & PAD_INPUT_A ) g_janru = 1;
if( key & PAD_INPUT_B ) g_janru = 2;
if( key & PAD_INPUT_C ) g_janru = 3;
if( key & PAD_INPUT_X ) g_janru = 4;
/*switch(g_janru)
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;*/
}
//色々なファイルの読み込み
int LoadFiles(){
//画像ファイルの読み込み
//if ( medaka1 = LoadGraph("media\\めだか.png") == -1) return -1;
if (LoadQuestion("media\\Que_monogatari.txt")==-1) return -1;
kotaewaku[1] = LoadGraph("media\\答え枠1.png");
kotaewaku[2] = LoadGraph("media\\答え枠2.png");
kotaewaku[3] = LoadGraph("media\\答え枠3.png");
if ( kotaewaku[1] == -1 || kotaewaku[2] == -1 || kotaewaku[3] == -1){
return -1;
}
return 1;
}#include "myhelper.h"
#include "mymain.h"
//グローバル変数
int g_lasttime; //前回のループ終了時間(ミリ秒)
float g_frametime = 0.017f; //1フレームの表示にかかった時間(秒)
// プログラムの開始関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
if (strcmp(lpCmdLine, "-f") != 0) ChangeWindowMode(TRUE);
//DXライブラリの初期化処理
if( DxLib_Init() == -1 ) return -1;
//描画対象を裏画面に設定
SetDrawScreen(DX_SCREEN_BACK);
//ファイルの読み込み
if( LoadFiles() == -1 ) return -1;
//画面サイズ(当たり判定用)の初期化
Rect2D gf = { {-64,-64}, {640+64,480+64}, 768, 608};
memcpy( &g_framerect, &gf, sizeof(Rect2D) );
//スクロール開始点の初期化
g_current_field_pos.x = 0;
g_current_field_pos.y = 0;
//ステージサイズの初期化
Rect2D gs = { {0,0}, {639,479}, 640,480} ;
memcpy( &g_stagesize, &gs, sizeof(Rect2D) );
//メインループ
g_lasttime = GetNowCount() & INT_MAX;
while(ProcessMessage()==0 && CheckHitKey(KEY_INPUT_ESCAPE)==0){
ClsDrawScreen(); //画面を消去
MyMain();
ScreenFlip(); //画面を切り替え
//1ループにかかった時間を計測
int curtime = GetNowCount() & INT_MAX;
g_frametime = (float)(curtime - g_lasttime) / 1000.0f;
g_lasttime = curtime;
if (g_frametime > 0.03f) g_frametime = 0.03f;
}
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
//スクロール用データ
Rect2D g_framerect = { {-64,-64}, {640+64,480+64}, 768, 608}; //画面領域(当たり判定)
Point2D g_current_field_pos = {0,0}; //現在の左上座標
Rect2D g_stagesize = { {0,0}, {639,479}, 640,480}; //ステージサイズ
//スクロール用関数
//データ上の座標を画面表示用座標に変更する
Point2D PosInView(Point2D in){
return SubVector(in, g_current_field_pos);
}
//そのX座標版とY座標版
int XInView(float inx){
return (int)(inx - g_current_field_pos.x);
}
int YInView(float iny){
return (int)(iny - g_current_field_pos.y);
}
/*画面を左へスクロール
(自キャラから200ピクセルを保つようスクロール)*/
void ScrollToLeft(float jikiposx){
//スクロール可能かをチェック
if ((int)jikiposx - SCROLL_LIMIT > (int)g_stagesize.lefttop.x){
g_current_field_pos.x = jikiposx - SCROLL_LIMIT;
g_framerect.lefttop.x = g_current_field_pos.x - 64;
g_framerect.lefttop.y = g_current_field_pos.y - 64;
g_framerect.rightbottom.x = g_current_field_pos.x + 640 + 64;
g_framerect.rightbottom.y = g_current_field_pos.y + 480 + 64;
}
}
/*画面を右へスクロール
(自キャラから200ピクセルを保つようスクロール)*/
void ScrollToRight(float jikiposx){
if ((int)jikiposx + SCROLL_LIMIT < (int)g_stagesize.rightbottom.x){
g_current_field_pos.x = jikiposx - (640 - SCROLL_LIMIT);
g_framerect.lefttop.x = g_current_field_pos.x - 64;
g_framerect.lefttop.y = g_current_field_pos.y - 64;
g_framerect.rightbottom.x = g_current_field_pos.x + 640 + 64;
g_framerect.rightbottom.y = g_current_field_pos.y + 480 + 64;
}
}
/*画面を上へスクロール*/
void ScrollToUp(float jikiposy){
//スクロール可能かをチェック
if ((int)jikiposy - SCROLL_LIMIT > (int)g_stagesize.lefttop.y){
g_current_field_pos.y = jikiposy - SCROLL_LIMIT;
g_framerect.lefttop.x = g_current_field_pos.x - 64;
g_framerect.lefttop.y = g_current_field_pos.y - 64;
g_framerect.rightbottom.x = g_current_field_pos.x + 640 + 64;
g_framerect.rightbottom.y = g_current_field_pos.y + 480 + 64;
}
}
/*画面を下へスクロール*/
void ScrollToDown(float jikiposy){
if ((int)jikiposy + SCROLL_LIMIT < (int)g_stagesize.rightbottom.y){
g_current_field_pos.y = jikiposy - (480 - SCROLL_LIMIT);
g_framerect.lefttop.x = g_current_field_pos.x - 64;
g_framerect.lefttop.y = g_current_field_pos.y - 64;
g_framerect.rightbottom.x = g_current_field_pos.x + 640 + 64;
g_framerect.rightbottom.y = g_current_field_pos.y + 480 + 64;
}
}
/*スクロールを計算に入れた描画関数*/
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness){
DrawLine(XInView(x1), YInView(y1), XInView(x2), YInView(y2),
Color, Thickness);
}
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag){
DrawCircle(XInView(x), YInView(y), (int)r, Color, FillFlag);
}
/*アニメーション表示をする関数
画像を表示する座標xとy、
イメージデータの配列imgarray、総コマ数framenum、アニメの表示速度fps
アニメーション用の一時データanimtmpを引数とする。
1枚絵を表示する場合は、
imgarrayにint型変数のアドレス、allframeに1、fpsに1.0fを指定すること。
*/
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps){
//現在の経過秒数を求める
float t = (float)( GetNowCount() & INT_MAX );
//表示すべきコマ数を求める
int animpat = (int)(t/(1000/fps)) % allframe;
//そのコマを描画
DrawRotaGraph(XInView(x),YInView(y), ExtRate, Angle, imgarray[animpat], TRUE, TurnFlag);
}
/*ベクトルを作成する関数
入力ベクトルを正規化してから長さを掛ける*/
Vector CreateVector(Vector in, float veclen){
Vector result;
in = Normalize(in);
result.x = in.x * veclen;
result.y = in.y * veclen;
return result;
}
/*ベクトルの足し算を行う関数*/
Vector AddVector(Vector v1, Vector v2){
Vector result;
result.x = v1.x + v2.x;
result.y = v1.y + v2.y;
return result;
}
/*ベクトルの引き算を行う関数
座標からベクトルを求める場合にも使える
その場合v1は終点、v2は始点とする*/
Vector SubVector(Vector v1, Vector v2){
Vector result;
result.x = v1.x - v2.x;
result.y = v1.y - v2.y;
return result;
}
/*座標に速度ベクトルを足す関数(等速運動用)
g_frametimeを考慮する*/
Vector AddVectorInFrameTime(Vector pos, Vector speed){
Vector result;
result.x = pos.x + speed.x * g_frametime;
result.y = pos.y + speed.y * g_frametime;
return result;
}
/*座標に速度ベクトルと加速度を足す関数(等加速度運動用)
g_frametimeを考慮する*/
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel){
Vector result;
result.x = pos.x + speed.x * g_frametime + accel.x * pow(g_frametime,2) / 2;
result.y = pos.y + speed.y * g_frametime + accel.y * pow(g_frametime,2) / 2;
return result;
}
/*ベクトルを正規化する関数*/
Vector Normalize(Vector in){
Vector result;
float l = sqrt( in.x * in.x + in.y * in.y );
result.x = in.x / l;
result.y = in.y / l;
return result;
}
/*内積を求める関数*/
float DotProduct(Vector v1, Vector v2){
return v1.x * v2.x + v1.y * v2.y;
}
/*外積を求める関数*/
float CrossProduct(Vector v1, Vector v2){
return v1.x * v2.y - v1.y * v2.x;
}
/*ベクトルを回転させる関数*/
Vector RotateVector(Vector in, float radian){
Vector result;
result.x = -sin(radian)*in.y + cos(radian)*in.x;
result.y = cos(radian)*in.y + sin(radian)*in.x;
return result;
}
/*ベクトルの長さの二乗を求める関数
長さが必要なときはsqrtで平方根を求める*/
float VectorLengthSquare(Vector in){
return in.x * in.x + in.y * in.y;
}
/*Line2Dを描画する関数*/
void DrawLine2D(Line2D in, int Color, int Thickness){
DrawLine(XInView(in.startpos.x), YInView(in.startpos.y),
XInView(in.endpos.x), YInView(in.endpos.y), Color, Thickness);
}
/*Ball2Dを描画する関数*/
void DrawBall2D(Ball2D in, int Color, int FillFlag){
DrawCircle(XInView(in.position.x), YInView(in.position.y),
(int)in.hankei, Color, FillFlag);
}
/*線の傾きを求めてLine2Dのメンバkatamukiにセットする関数*/
void SetLine2DKatamuki(Line2D *in){
in->katamuki = atan2(in->endpos.y - in->startpos.y, in->endpos.x - in->startpos.x);
}
/*Ball2DとLine2Dの当たり判定を行う関数*/
bool HitTestLineAndBall(Line2D linein, Ball2D ballin){
Vector avec, bvec;
avec = SubVector(ballin.position, linein.startpos);
bvec = SubVector(linein.endpos, linein.startpos);
float dot = DotProduct(avec, bvec); //内積を求める
float bl = VectorLengthSquare(bvec); //ベクトルbの長さの二乗を求める
if ( (dot > -ZEROVALUE) && (dot < bl) ) { //衝突の可能性有り
//円と線の距離を求める
//ボールの中心から垂直におろした線の交点を求める
Vector bnvec = Normalize(bvec); //ベクトルbの正規化
float dot2 = DotProduct(avec, bnvec);
bnvec.x *= dot2;
bnvec.y *= dot2;
Point2D kouten = AddVector(linein.startpos, bnvec);
Vector dist = SubVector(ballin.position, kouten);
float al = VectorLengthSquare(dist);
#ifdef _DEBUG
DrawBall2D(ballin, GetColor(128,128,128),FALSE);
DrawLineInView(linein.startpos.x, linein.startpos.y,
linein.startpos.x+avec.x, linein.startpos.y+avec.y, 65535,1);
DrawLineInView(linein.startpos.x, linein.startpos.y,
kouten.x, kouten.y, GetColor(255,0,0),1);
DrawLineInView(kouten.x, kouten.y,
ballin.position.x, ballin.position.y, GetColor(255,0,0),1);
#endif
if ( al < (ballin.hankei * ballin.hankei) ){
return TRUE;
}
}
return FALSE;
}
/*頂点と線の位置関係を調べる関数
線の左または上側にあればTRUE、右または下側にあればFALSEを返す*/
bool IsPointAtLineFace(Line2D linein, Point2D ptin){
Vector avec, bvec;
avec = SubVector(ptin, linein.startpos);
bvec = SubVector(linein.endpos, linein.startpos);
float cross = CrossProduct(avec, bvec);
//外積が正なら点は線の表側(左側)にある
if ( cross > -ZEROVALUE ) return TRUE;
return FALSE;
}
/*Line2D同士の当たり判定を行う関数*/
bool HitTestLineAndLine(Line2D line1, Line2D line2){
Vector avec, bvec, cvec, dvec, evec, fvec;
avec = SubVector(line1.endpos, line1.startpos); //a2-a1
bvec = SubVector(line2.startpos, line1.startpos); //b1-a1
cvec = SubVector(line2.endpos, line1.startpos); //b2-a1
dvec = SubVector(line2.endpos, line2.startpos); //b2-b1
evec = SubVector(line1.startpos, line2.startpos); //a1-b1
fvec = SubVector(line1.endpos, line2.startpos); //a2-b1
float a,b,c,d;
a = CrossProduct(avec, bvec);
b = CrossProduct(avec, cvec);
c = CrossProduct(dvec, evec);
d = CrossProduct(dvec, fvec);
if( ((a*b) < ZEROVALUE) && ((c*d) < ZEROVALUE) ){
return TRUE;
}
return FALSE;
}
/*Ball2D同士の当たり判定を行う関数*/
bool HitTestBallAndBall(Ball2D ball1, Ball2D ball2){
#ifdef _DEBUG
DrawBall2D(ball1, GetColor(128,128,128),FALSE);
DrawBall2D(ball2, GetColor(128,128,128),FALSE);
#endif
if ( pow(ball1.position.x - ball2.position.x, 2) + pow(ball1.position.y - ball2.position.y,2)
< pow(ball1.hankei+ball2.hankei, 2) ){
return TRUE;
}else{
return FALSE;
}
}
/*Point2DとRect2Dの当たり判定を行う関数*/
bool HitTestPointAndBox(Rect2D rect, Point2D pt){
if ( (rect.lefttop.x < pt.x) && (pt.x < rect.rightbottom.x) &&
(rect.lefttop.y < pt.y) && (pt.y < rect.rightbottom.y) ){
return TRUE;
}
return FALSE;
}
//シンプルタイマー関数
const int MAXTIMER = 32;
int g_goaltimes[MAXTIMER];
/*タイマーに目標値を設定して始動させる関数
目標値timeはミリ秒で設定する*/
void SetSimpleTimer(int idx, int time){
if(idx>MAXTIMER) return;
g_goaltimes[idx] = (GetNowCount() & INT_MAX) + time;
}
/*タイマーの結果を取得する関数
返値が負ならまだ目標値に達していない
正なら目標値を超えている*/
int GetPassedTime(int idx){
return (GetNowCount() & INT_MAX) - g_goaltimes[idx];
}#include "DxLib.h"
#include <limits.h>
#include <math.h>
//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki; //傾きをラジアン値で記録
Vector speed; //移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei; //半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};
//問題についての構造体
struct Mondai{
int Qnum; //問題数
int Qkeishiki; //問題形式1=4択 2=記述問題 3=○×クイズ
int marubatu; //○か×か 1=○ 2=×
char Qbunshou[80]; //問題文
char Answer_one[40]; //答え1つ目(正しい)
char Answer_two[40]; //答え2つ目(間違ってはいない)
char ans_one[20],ans_two[20],ans_three[20]; //4択の間違え1、2、3
};
//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);
//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect; //画面領域(当たり判定)
extern Point2D g_current_field_pos; //現在の左上座標
extern Rect2D g_stagesize; //ステージサイズ
//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;1,2,0
めだかボックス第1巻の最初の一言は何か。
世界は平凡か?,世界は平凡か?
0,0,0
char型に0を入れていますが、あまり気にしないでいただけると嬉しいです…
というコードでmymain.cppとmymain.hは自分で書いたコードで、
myhelper.cppとmyhelper.hは解説書についていたコードです。
[1.3]ウィンドウが開いてすぐに、○○○.txtは動作を停止しました、というメッセージがでてしまいます。
[1.4] どうすれば正しくメモ帳が読み込まれるのかがわかりません。
できたら、説明もしていただけると嬉しいです。なにぶん、初めての状況ですので…
[2] 環境
[2.1] OS : Windows
[2.2] コンパイラ名 : VC++ 2008EE DXLib使用
[3] その他
・あまり理解できないかもしれないので、わかりやすく説明、回答していただけると、とてもありがたいです!
とても長いコードですいません。
抜粋がしづらかったので…