やっぱりエラーが出る!!なんで??

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Tomo
記事: 16
登録日時: 10年前
住所: 埼玉県

やっぱりエラーが出る!!なんで??

#1

投稿記事 by Tomo » 8年前

こんばんは
全然エラーが直りません。以下のコードのどこが間違っているのでしょうか?
理想ではData.txtの1行が読み込めているはずなのですが、表示画面に遷移したとたんdebug assertion Failedになります。
vector out of range と書いてあるので「存在しないメモリにアクセスしてるよ」と言われてるそうなのですがpush_backで末尾に追加されていればString[0][1]には単語(15文字以内)が格納されているはずです。また、vectorを使用していないBufferも表示してみましたがエラーは出ないものの何も表示されませんいったい何がどうなっているのでしょうか?
環境 windows10,visualstudio2015community,C++,Dxライブラリ使用
これ以外のコードはファイルはhttp://dixq.net/forum/viewtopic.php?f=3&t=18326に載っています。

Load.h

コード:

#pragma once
#include <cstring>
#include <sstream>
#include <vector>

#define WORD_COUNTS 3000//記憶可能な単語種数
#define CHARACTERS 64//記憶可能な文字数

class Load{
private:
	int FileHandle;
	int Case;
	int Now;
	std::string Buffer;
	std::vector<std::vector<std::string>> String{
		{"EnglishWord"},
		{"JapaneseWord1"},
		{"JapaneseWord2"},
		{"JapaneseWord3"},
		{"EnglishSentence"},
		{"JapaneseSentence"}
	};
	


public:
	Load();
	~Load();
	int LoadData();
	void Draw();
};
Load.cpp

コード:

#include "Load.h"
#include "DxLib.h"
#include "Common.h"

#include <fstream>


Load::Load(){
	Case = 0;
	Now = 0;
}


int Load::LoadData(){
	std::ifstream ifs("Load/Data.txt");
	if (ifs.fail()) {
		DrawString(20, 20, "ファイル読み込み失敗", Color);
		return -1;
	}
	else{
		DrawString(20, 20, "ファイル読み込み成功", Color);
		while (getline(ifs, Buffer)){
			std::string tmp;
			std::istringstream stream(Buffer);
			int i = 0;
			while (getline(stream, tmp,'/')){
				String[i].push_back(tmp);
				i++;
			}
		}

		return 0;
	}
	ifs.close();
	
}

void Load::Draw(){
	DrawString(0, 30, String[0][1].c_str(), Color);
	DrawString(0, 0, Buffer.c_str(), Color);
}


Load::~Load(){

}
StateTransition.h

コード:

#pragma once
#include "ScreenTransition.h"

#include "TitleScreen.h"
#include "ChoiceScreen.h"

#include "Load.h"//一時的

class StateTransition{
private:
	int NowStateNum;
	int BackScreenGh;
	ScreenTransition* screen[4];
	TitleScreen titleS;
	ChoiceScreen choiceS;
	Load* load;//一時的
public:
	StateTransition();
	~StateTransition();
	void Draw();
	void Transition();

};
StateTransition.cpp

コード:

#include "StateTransition.h"
#include "Common.h"//完成後必要ない
#include "Keyboard.h"
#include "DxLib.h"



StateTransition::StateTransition(){
	NowStateNum = 0;
	BackScreenGh= LoadGraph("Graph/backscreen.png");//640*400
	
	screen[0] = &titleS;
	screen[1] = &choiceS;
	load = new Load;
}

void StateTransition::Draw(){
	DrawGraph(0, 0, BackScreenGh, TRUE);
}

void StateTransition::Transition() {
	while (!ScreenFlip() && !ProcessMessage() && !ClearDrawScreen()) {
		Keyboard::Instance()->Update();
		Draw();
		switch (NowStateNum) {
		case 0:
			screen[0]->Transition();
			if(screen[0]->GetActiveFlag()==false)NowStateNum++;
			break;
		case 1:
			screen[1]->Transition();
			if (screen[1]->GetActiveFlag() == false)NowStateNum++;
			break;
		default:
			DrawFormatString(320, 150, Color, "%d", NowStateNum);
			load->Draw();
			break;
		}
		//if (Keyboard::Instance()->GetPressingCount(KEY_INPUT_RETURN) == 1)NowStateNum++;
		if (Keyboard::Instance()->GetPressingCount(KEY_INPUT_ESCAPE) != 0)break;
	}
}

StateTransition::~StateTransition(){
}
main.cpp

コード:

#include <DxLib.h>
#include "Common.h"
#include "Load.h"
#include "StateTransition.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	SetGraphMode(WIDTH, HEIGHT, BITS);
	SetMainWindowText(TITLE);
	ChangeWindowMode(TRUE);
	DxLib_Init();
	SetDrawScreen(DX_SCREEN_BACK);
	SetAlwaysRunFlag(TRUE);
	ChangeFont("游明朝");

	Load* load = new Load;
	load->LoadData();
	{
		StateTransition st;
		st.Transition();
	}

	DxLib_End();
	delete load;
	return 0;
}
Data.txt

コード:

単語(15文字以内)/単語訳1/単語訳2/単語訳3/文(63文字以内)/文訳
follow/~(の後)に続く/<指示・方針など>に従う//[follow] her advice/彼女の助言に従う
supply/供給する/支給する//[supply] the city [with] water/その都市に水を供給する

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: やっぱりエラーが出る!!なんで??

#2

投稿記事 by みけCAT » 8年前

蜜柑 さんが書きました:以下のコードのどこが間違っているのでしょうか?
  • StateTransitionクラスでnewしたLoadクラスのインスタンスをdeleteしていないのは良くないでしょう。
  • WinMain関数でLoadクラスを使ってデータを読み込ませ、それを全く使わずに消しているのは間違っているとは言えないですが、不自然でしょう。
  • StateTransitionクラスのloadでデータを読み込ませる前にDraw()を呼んでいるのが、おそらく質問にあるエラーの原因でしょう。
蜜柑 さんが書きました:これ以外のコードはファイルはhttp://dixq.net/forum/viewtopic.php?f=3&t=18326に載っています。
ChoiceScreen.hがこのページにもリンク先のページにも無いようですが、「これ以外のコード」の定義は何でしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Tomo
記事: 16
登録日時: 10年前
住所: 埼玉県

Re: やっぱりエラーが出る!!なんで??

#3

投稿記事 by Tomo » 8年前

みけCATさんありがとうございます。おかげで解決することができました。
Loadクラスはシングルトンクラスにするつもりだったので自分で勝手に勘違いしていました。
またdeleteのし忘れですね。気を付けます。
みけCAT さんが書きました:ChoiceScreen.hがこのページにもリンク先のページにも無いようですが、「これ以外のコード」の定義は何でしょうか?
「これ以外のコード」とはここにあるコードと合わせればプログラムが動きます。ということでしたが載せていないコードがありました。
これじゃ動きませんね。失礼しました。
その質問の後にクラスを追加していました。
一応以下にコードを書いておきます。Dataクラスは消す可能性が高いですが...
Choice.h

コード:

#pragma once
#include "Screen.h"

class Choice{
private:
	bool Next;
	int LearnStart;
	int LearnEnd;
	int LearnNum;
	bool random;

public:
	Choice();
	~Choice();
	void Draw();
	void setstart();
	void setend();
	void setnumber();
	void setrandom();
	bool GetNext();
	void SetNext(int);
};
Choice.cpp

コード:

#include "Choice.h"
#include "Common.h"
#include "Keyboard.h"
#include "DxLib.h"
#include "Data.h"

Choice::Choice() {
	Next = 0;
	LearnStart = 0;
	LearnEnd = 0;
	LearnNum = 0;
	random = false;
}

void Choice::Draw() {
	DrawString(20, 30, "初期設定項目を入力、選択してください", Color);
	if (LearnStart != 0) {
		DrawString(40, 60, "学習範囲の始めの値", Color);
		DrawFormatString(40, 90, Color, "%d", LearnStart);
	}
	if (LearnEnd != 0) {
		DrawString(40, 120, "学習範囲の終わりの値", Color);
		DrawFormatString(40, 150, Color, "%d", LearnEnd);
	}
	if (LearnNum != 0) {
		DrawString(40, 180, "学習単語数", Color);
		DrawFormatString(40, 210, Color, "%d", LearnNum);
	}
}

void Choice::setstart(){
	DrawString(40, 60, "学習範囲の始めの値を入力してください", Color);
	LearnStart = KeyInputNumber(40, 90, 1000-20, 1, FALSE);
	if (LearnStart != 0)Next = true;
}

void Choice::setend(){
	DrawString(40, 120, "学習範囲の終わりの値を入力してください", Color);
	LearnEnd = KeyInputNumber(40, 150, 1000, LearnStart+20, FALSE);
	if (LearnEnd != 0)Next = true;
}

void Choice::setnumber(){
	DrawString(40, 180, "学習単語数を入力してください", Color);
	LearnNum = KeyInputNumber(40, 210, LearnEnd - LearnStart + 1, 20, FALSE);
	if (LearnNum != 0)Next = true;
}

void Choice::setrandom(){
	DrawString(40, 240, "問題出題時にランダムにするかを選択してください", Color);
	DrawString(40, 270, "(←→キーで選択してください)", Color);
	if (Keyboard::Instance()->GetPressingCount(KEY_INPUT_RIGHT) == 1)random = false;
	if (Keyboard::Instance()->GetPressingCount(KEY_INPUT_LEFT) == 1)random = true;
	if(random==true)DrawString(40, 300, "ランダム", Color);
	else{ DrawString(160, 300, "問題番号順", Color); }
	if (Keyboard::Instance()->GetPressingCount(KEY_INPUT_RETURN) == 1) {
		Data::Instance()->SetParameter(LearnStart, LearnEnd, LearnNum, random);
		Next = true;
	}
}

bool Choice::GetNext(){
	return Next;
}

void Choice::SetNext(int next){
	Next = next;
}

Choice::~Choice() {

}
ChoiceScreen.h

コード:

#pragma once
#include "ScreenTransition.h"

class ChoiceScreen:public ScreenTransition{
private:
	Choice* choice;
public:
	ChoiceScreen();
	~ChoiceScreen();
	void Transition();

};


ChoiceScreen.cpp

コード:

#include "ChoiceScreen.h"

ChoiceScreen::ChoiceScreen(){
	NowScreenNum = 0;
	active = true;
	choice = new Choice;
}

void ChoiceScreen::Transition(){
	switch (NowScreenNum){
	case 0:
		choice->Draw();
		choice->setstart();
		if (choice->GetNext() == true)NowScreenNum++;
		break;
	case 1:
		choice->Draw();
		choice->setend();
		if (choice->GetNext() == true)NowScreenNum++;
		break;
	case 2:
		choice->Draw();
		choice->setnumber();
		if (choice->GetNext() == true)NowScreenNum++;
		break;
	case 3:
		choice->Draw();
		choice->setrandom();
		if (choice->GetNext() == true)NowScreenNum++;
		break;
	case 4:
		active = false;
	}
	choice->Draw();
	choice->SetNext(false);
}


ChoiceScreen::~ChoiceScreen(){
	delete choice;
}

Data.h

コード:

#pragma once
#include "Singleton.h"

class Data:public Singleton<Data>{
	Data();
	friend Singleton<Data>;

private:
	int Start;
	int End;
	int Num;
	bool random;

public:
	void SetParameter(int,int,int,bool);


};
Data.cpp

コード:

#include "Data.h"

Data::Data(){
	Start = 0;
	End = 0;
	Num = 0;
	random = false;
}

void Data::SetParameter(int st,int en, int num,bool ran){
	Start = st;
	End = en;
	Num = num;
	random = ran;
}


閉鎖

“C言語何でも質問掲示板” へ戻る