ファイルを読み込んで変数に入れたり再生する

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
DELTA-Ⅲ
記事: 21
登録日時: 11年前

ファイルを読み込んで変数に入れたり再生する

#1

投稿記事 by DELTA-Ⅲ » 10年前

今デスクトップアクセサリの様な物を作っているのですが、
テキストファイルを読み込んで変数に入れる(テキストがaaa = 45だったら45の部分を変数に入れる。)方法や
音楽ファイル(.mp3)を自動で読み込んで再生する方法を探しているのですが見つかりません。
見落としだと思いますがテキストファイルの方は全く分からず、困っています。
どうすればいいでしょうか、教えてください。

説明不足等があったらすみません。

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

Re: ファイルを読み込んで変数に入れたり再生する

#2

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

DELTA-Ⅲ さんが書きました:どうすればいいでしょうか、教えてください。
まず、ターゲットのOSと利用しているプログラミング言語を教えていただけますか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

DELTA-Ⅲ
記事: 21
登録日時: 11年前

Re: ファイルを読み込んで変数に入れたり再生する

#3

投稿記事 by DELTA-Ⅲ » 10年前

みけCAT さんが書きました:
DELTA-Ⅲ さんが書きました:どうすればいいでしょうか、教えてください。
まず、ターゲットのOSと利用しているプログラミング言語を教えていただけますか?
すみません。OSはWin7で言語はC++でDXライブラリを使っています。

アバター
Ketty
記事: 103
登録日時: 11年前

Re: ファイルを読み込んで変数に入れたり再生する

#4

投稿記事 by Ketty » 10年前

こんにちは(^^)
DELTA-Ⅲ さんが書きました: 見落としだと思いますがテキストファイルの方は全く分からず、困っています。
DXライブラリにはファイル関連の関数がありますよ。
私は、以下の関数の組み合わせで実現していますが、DELTA-Ⅲさんの問題はなんでしょう?

FileRead_open・・・ファイルopenする
http://homepage2.nifty.com/natupaji/DxL ... html#R19N1

FileRead_gets・・・openしたファイルを1行読み取る
http://homepage2.nifty.com/natupaji/DxL ... html#R19N8

FileRead_eof・・・読み取りが最後の行まで達したか確認する
http://homepage2.nifty.com/natupaji/DxL ... html#R19N7

FileRead_close・・・ファイルcloseする
http://homepage2.nifty.com/natupaji/DxL ... html#R19N3

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

Re: ファイルを読み込んで変数に入れたり再生する

#5

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

DELTA-Ⅲ さんが書きました:テキストファイルを読み込んで変数に入れる(テキストがaaa = 45だったら45の部分を変数に入れる。)方法
適当に作ってみました。仕様の解釈が間違っていたらごめんなさい。

コード:

#include <DxLib.h>
#include <map>
#include <string>

/*
aaa = 45 のようなテキストを読み込んで返す。
=の前後のスペースは0個以上の任意の個数許容する(無視される)。
項目名が被った場合は、一番最後に入力したものを反映する。

BNFもどき
<テキストファイル> ::= <行> | <行> <改行文字> | <行> <改行文字> <テキストファイル>
<改行文字> ::= 省略 
<行> ::= <項目名> <空白列> "=" <空白列> <データ> | <コメント>
<空白列> ::= "" | " " <空白列>
<項目名> ::= (=と改行以外の任意の文字の長さ0以上の列)
<データ> ::= (改行以外の任意の文字の長さ0以上の列)
<コメント> ::= (改行以外の任意の文字の長さ0以上の列)
*/
std::map<std::string, std::string> readText(const char *fileName) {
	int handle = FileRead_open(fileName, FALSE);
	if (handle == 0) throw std::string("FileRead_open error");

	std::map<std::string, std::string> result; // 読み込んだ結果 
	std::string name = ""; // 項目名
	std::string data = ""; // データ
	std::string pendingInput = ""; // 無視されるかもしれない入力
	bool isReadingName = true; // 項目名またはコメントの入力中か
	bool isReadingValidData = false; // 空白の後の、確実にデータである入力の読み込み中か
	while (!FileRead_eof(handle)) {
		int input = FileRead_getc(handle);
		if (input == -1) {
			FileRead_close(handle);
			throw std::string("FileRead_getc error");
		}
		if (isReadingName) {
			// 項目名またはコメントの入力中
			if (input == '\r' || input == '\n') {
				// =が現れずに項目名(仮)の入力が終わったので、コメントだった
				name = "";
				pendingInput = "";
			} else if (input == ' ') {
				// 空白は=の前の無視するべきものかもしれないので、保留する
				pendingInput.push_back((std::string::value_type)input);
			} else if (input == '=') {
				// =が現れたので、データの入力に移行する
				data = "";
				isReadingName = false;
				isReadingValidData = false;
			} else {
				// 入力を名前に反映させる
				name.append(pendingInput);
				name.push_back((std::string::value_type)input);
				pendingInput = "";
			}
		} else {
			// データの入力中
			if (input == '\r' || input == '\n') {
				// データの入力を終了して保存し、次の項目名(仮)の入力に移行する
				result[name] = data;
				name = "";
				pendingInput = "";
				isReadingName = true;
			} else if (input == ' ') {
				// 空白なので、=の後のものは無視する
				if (isReadingValidData) data.push_back((std::string::value_type)input);
			} else {
				// 入力をデータに反映させる
				data.push_back((std::string::value_type)input);
				isReadingValidData = true;
			}
		}
	}
	// 最終行のデータを保存する
	if (!isReadingName) result[name] = data;

	FileRead_close(handle);
	return result;
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
	if (ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() != 0) return -1;
	SetDrawScreen(DX_SCREEN_BACK);

	bool readError = false;
	std::string errorMessage = "";

	std::string hensuu = ""; // 「テキストがaaa = 45だったら45の部分を変数に入れる」に使用する変数

	std::map<std::string, std::string> dataFromTextFile;
	try {
		dataFromTextFile = readText("input.txt");
	} catch (std::string e) {
		errorMessage = e;
		readError = true;
	}

	// テキストがaaa = 45だったら45の部分を変数に入れる
	if (dataFromTextFile.find("aaa") != dataFromTextFile.end()) {
		hensuu = dataFromTextFile["aaa"];
	}

	while (ProcessMessage() == 0 && ClearDrawScreen() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) {
		if (readError) {
			DrawFormatString(20, 20, GetColor(255, 0, 0), "エラー発生 : %s", errorMessage.c_str()); 
		} else {
			DrawFormatString(20, 20, GetColor(0, 255, 0), "変数 = %s", hensuu.c_str());
			int ypos = 40;
			for (std::map<std::string, std::string>::iterator it = dataFromTextFile.begin();
			it != dataFromTextFile.end(); it++) {
				DrawFormatString(20, ypos, GetColor(255, 255, 25), "%s = %s", it->first.c_str(), it->second.c_str());
				ypos += 20;
			}
		}
		ScreenFlip();
	}

	DxLib_End();
	return 0;
}
input.txt

コード:

hoge = 346
fuga = mareitaso
aaa = 45
kugyu = kugimiyarie
DELTA-Ⅲ さんが書きました:音楽ファイル(.mp3)を自動で読み込んで再生する方法
「自動で」の定義がよくわかりませんが、音楽ファイルの読み込みはLoadSoundMem関数で、再生はPlaySoundMem関数でできるはずです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

DELTA-Ⅲ
記事: 21
登録日時: 11年前

Re: ファイルを読み込んで変数に入れたり再生する

#6

投稿記事 by DELTA-Ⅲ » 10年前

みけCAT さんが書きました:適当に作ってみました。仕様の解釈が間違っていたらごめんなさい。
大丈夫です。後追加があってすみませんが、aaa = 31,14 等の変数を分割させて変数を保存する方法がありますか?
みけCAT さんが書きました:「自動で」の定義がよくわかりませんが、
説明不足ですみません。特定のフォルダ(sound/)にあるファイル名を読み込み、
読み込んだファイル名を使って音楽ファイルを読み込むといった感じものです。
説明不足ですみませんでした。

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

Re: ファイルを読み込んで変数に入れたり再生する

#7

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

DELTA-Ⅲ さんが書きました:
みけCAT さんが書きました:適当に作ってみました。仕様の解釈が間違っていたらごめんなさい。
大丈夫です。後追加があってすみませんが、aaa = 31,14 等の変数を分割させて変数を保存する方法がありますか?
あります。例えばデータをstd::vector<std::string>に入れるようにして、','を読み込んだら今までのデータをpush_backして次のデータの読み込みを0文字から開始するようにするといいでしょう。
あとでまたサンプルを作るかもしれません。
DELTA-Ⅲ さんが書きました:
みけCAT さんが書きました:「自動で」の定義がよくわかりませんが、
説明不足ですみません。特定のフォルダ(sound/)にあるファイル名を読み込み、
読み込んだファイル名を使って音楽ファイルを読み込むといった感じものです。
説明不足ですみませんでした。
ファイル名の読み込みはDXライブラリのAPIだけではできなそうですが、Windows APIを使えばできるはずです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: ファイルを読み込んで変数に入れたり再生する

#8

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

みけCAT さんが書きました:あとでまたサンプルを作るかもしれません。
作ってみました。

コード:

#include <DxLib.h>
#include <map>
#include <vector>
#include <string>

/*
aaa = 45 のようなテキストを読み込んで返す。
=の前後のスペースは0個以上の任意の個数許容する(無視される)。
項目名が被った場合は、一番最後に入力したものを反映する。

BNFもどき
<テキストファイル> ::= <行> | <行> <改行文字> | <行> <改行文字> <テキストファイル>
<改行文字> ::= 省略 
<行> ::= <項目名> <空白列> "=" <空白列> <データリスト> | <コメント>
<空白列> ::= "" | " " <空白列>
<データリスト> ::= <データ> | <データ> "," <データリスト>
<項目名> ::= (=と改行以外の任意の文字の長さ0以上の列)
<データ> ::= (,と改行以外の任意の文字の長さ0以上の列)
<コメント> ::= (=と改行以外の任意の文字の長さ0以上の列)
*/
std::map<std::string, std::vector<std::string> > readText(const char *fileName) {
	int handle = FileRead_open(fileName, FALSE);
	if (handle == 0) throw std::string("FileRead_open error");

	std::map<std::string, std::vector<std::string> > result; // 読み込んだ結果 
	std::string name = ""; // 項目名
	std::vector<std::string> dataList; // データリスト
	std::string data = ""; // データ
	std::string pendingInput = ""; // 無視されるかもしれない入力
	bool isReadingName = true; // 項目名またはコメントの入力中か
	bool isReadingValidData = false; // 空白の後の、確実にデータである入力の読み込み中か
	while (!FileRead_eof(handle)) {
		int input = FileRead_getc(handle);
		if (input == -1) {
			FileRead_close(handle);
			throw std::string("FileRead_getc error");
		}
		if (isReadingName) {
			// 項目名またはコメントの入力中
			if (input == '\r' || input == '\n') {
				// =が現れずに項目名(仮)の入力が終わったので、コメントだった
				name = "";
				pendingInput = "";
			} else if (input == ' ') {
				// 空白は=の前の無視するべきものかもしれないので、保留する
				pendingInput.push_back((std::string::value_type)input);
			} else if (input == '=') {
				// =が現れたので、データの入力に移行する
				dataList.clear();
				data = "";
				isReadingName = false;
				isReadingValidData = false;
			} else {
				// 入力を名前に反映させる
				name.append(pendingInput);
				name.push_back((std::string::value_type)input);
				pendingInput = "";
			}
		} else {
			// データの入力中
			if (input == '\r' || input == '\n') {
				// データの入力を終了して保存し、次の項目名(仮)の入力に移行する
				dataList.push_back(data);
				result[name] = dataList;
				name = "";
				pendingInput = "";
				isReadingName = true;
			} else if (input == ' ') {
				// 空白なので、=の後のものは無視する
				if (isReadingValidData) data.push_back((std::string::value_type)input);
			} else if (input == ',') {
				// データの区切り
				dataList.push_back(data);
				data = "";
				isReadingValidData = true;
			} else {
				// 入力をデータに反映させる
				data.push_back((std::string::value_type)input);
				isReadingValidData = true;
			}
		}
	}
	// 最終行のデータを保存する
	if (!isReadingName) {
		dataList.push_back(data);
		result[name] = dataList;
	}

	FileRead_close(handle);
	return result;
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
	if (ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() != 0) return -1;
	SetDrawScreen(DX_SCREEN_BACK);

	bool readError = false;
	std::string errorMessage = "";

	std::vector<std::string> hensuu; // 「aaa = 31,14 等の変数を分割させて変数を保存する」に使用する変数

	std::map<std::string, std::vector<std::string> > dataFromTextFile;
	try {
		dataFromTextFile = readText("input.txt");
	} catch (std::string e) {
		errorMessage = e;
		readError = true;
	}

	if (dataFromTextFile.find("aaa") != dataFromTextFile.end()) {
		hensuu = dataFromTextFile["aaa"];
	}

	while (ProcessMessage() == 0 && ClearDrawScreen() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) {
		if (readError) {
			DrawFormatString(20, 20, GetColor(255, 0, 0), "エラー発生 : %s", errorMessage.c_str()); 
		} else {
			int ypos = 20;
			for (size_t i = 0; i < hensuu.size(); i++) {
				DrawFormatString(20, ypos, GetColor(0, 255, 0), "変数[%u] = %s", (unsigned int)i, hensuu[i].c_str());
				ypos += 20;
			}
			for (std::map<std::string, std::vector<std::string> >::iterator it = dataFromTextFile.begin();
			it != dataFromTextFile.end(); it++) {
				for (size_t i = 0; i < it->second.size(); i++) {
					DrawFormatString(20, ypos, GetColor(255, 255, 255), "%s[%u] = %s", it->first.c_str(), (unsigned int)i, it->second[i].c_str());
					ypos += 20;
				}
			}
		}
		ScreenFlip();
	}

	DxLib_End();
	return 0;
}
input.txt

コード:

hoge = 346
fuga = ayaneru,riesyon,mareitaso
aaa = 31,14
kugyu = kugimiya,rie
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: ファイルを読み込んで変数に入れたり再生する

#9

投稿記事 by かずま » 10年前

FileRead_getc() の代わりに FileRead_gets() を使ってみました。

コード:

#include <DxLib.h>
#include <map>
#include <vector>
#include <string>
#include <cstring> // strchr

using std::string;
typedef std::vector<string> ValueList;
typedef std::map<string, ValueList> Data;

string trim(const string& s)
{
	static const char spaces[] = " \t\n\v\f\r";
	size_t left = s.find_first_not_of(spaces);
	if (left == string::npos) return "";
	size_t right = s.find_last_not_of(spaces);
	return s.substr(left, right - left + 1);
}

string readText(const char *fileName, Data& data)
{
	int handle = FileRead_open(fileName, FALSE);
	if (handle == -1) return "FileRead_open error";
 
	char buf[256];
	while (FileRead_gets(buf, sizeof buf, handle) != -1) {
		char *p = buf, *q = std::strchr(p, '=');
		if (!q) continue;
		ValueList vals;
		string name = trim(string(p, q));
		while (p = q + 1, (q = std::strchr(p, ',')))
			vals.push_back(trim(string(p, q)));
		vals.push_back(trim(p));
		data[name].swap(vals);
	}

	FileRead_close(handle);
	return "";
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK);

	Data data;
	string errorMessage = readText("input.txt", data);

	while (!ScreenFlip() && !ProcessMessage() && !ClearDrawScreen()) {
		if (!errorMessage.empty())
			DrawFormatString(20, 20, GetColor(255, 0, 0), "エラー発生 : %s", errorMessage.c_str());
		else {
			int ypos = 20;
			for (auto it = data.begin(); it != data.end(); it++) {
 				for (size_t i = 0; i < it->second.size(); i++) {
					DrawFormatString(20, ypos, GetColor(255, 255, 255), "%s[%d] = %s",
						it->first.c_str(), (int)i, it->second[i].c_str());
					ypos += 20;
				}
			}
		}
	}

	DxLib_End();
	return 0;
}
map の data や、vector の vals のコピーがなくなるようにもしてあります。

DELTA-Ⅲ
記事: 21
登録日時: 11年前

Re: ファイルを読み込んで変数に入れたり再生する

#10

投稿記事 by DELTA-Ⅲ » 10年前

>>みけCATさん、かずまさん、返信ありがとうございます。
組み込もうとしたら変数に変化がないのかうまくいかず、
わからない状態です。どこがいけないでしょうか。
「ファイル名の読み込み」はちょっと後回しにしておきます。すみません・・・

コード:

#include "GV.h"
#include <map>
#include <vector>
#include <string>

/*
aaa = 45 のようなテキストを読み込んで返す。
=の前後のスペースは0個以上の任意の個数許容する(無視される)。
項目名が被った場合は、一番最後に入力したものを反映する。
 
BNFもどき
<テキストファイル> ::= <行> | <行> <改行文字> | <行> <改行文字> <テキストファイル>
<改行文字> ::= 省略 
<行> ::= <項目名> <空白列> "=" <空白列> <データリスト> | <コメント>
<空白列> ::= "" | " " <空白列>
<データリスト> ::= <データ> | <データ> "," <データリスト>
<項目名> ::= (=と改行以外の任意の文字の長さ0以上の列)
<データ> ::= (,と改行以外の任意の文字の長さ0以上の列)
<コメント> ::= (=と改行以外の任意の文字の長さ0以上の列)
*/
std::map<std::string, std::vector<std::string> > readText(const char *fileName) {
    int handle = FileRead_open(fileName, FALSE);
    if (handle == 0) throw std::string("FileRead_open error");
 
    std::map<std::string, std::vector<std::string> > result; // 読み込んだ結果 
    std::string name = ""; // 項目名
    std::vector<std::string> dataList; // データリスト
    std::string data = ""; // データ
    std::string pendingInput = ""; // 無視されるかもしれない入力
    bool isReadingName = true; // 項目名またはコメントの入力中か
    bool isReadingValidData = false; // 空白の後の、確実にデータである入力の読み込み中か
    while (!FileRead_eof(handle)) {
        int input = FileRead_getc(handle);
        if (input == -1) {
            FileRead_close(handle);
            throw std::string("FileRead_getc error");
        }
        if (isReadingName) {
            // 項目名またはコメントの入力中
            if (input == '\r' || input == '\n') {
                // =が現れずに項目名(仮)の入力が終わったので、コメントだった
                name = "";
                pendingInput = "";
            } else if (input == ' ') {
                // 空白は=の前の無視するべきものかもしれないので、保留する
                pendingInput.push_back((std::string::value_type)input);
            } else if (input == '=') {
                // =が現れたので、データの入力に移行する
                dataList.clear();
                data = "";
                isReadingName = false;
                isReadingValidData = false;
            } else {
                // 入力を名前に反映させる
                name.append(pendingInput);
                name.push_back((std::string::value_type)input);
                pendingInput = "";
            }
        } else {
            // データの入力中
            if (input == '\r' || input == '\n') {
                // データの入力を終了して保存し、次の項目名(仮)の入力に移行する
                dataList.push_back(data);
                result[name] = dataList;
                name = "";
                pendingInput = "";
                isReadingName = true;
            } else if (input == ' ') {
                // 空白なので、=の後のものは無視する
                if (isReadingValidData) data.push_back((std::string::value_type)input);
            } else if (input == ',') {
                // データの区切り
                dataList.push_back(data);
                data = "";
                isReadingValidData = true;
            } else {
                // 入力をデータに反映させる
                data.push_back((std::string::value_type)input);
                isReadingValidData = true;
            }
        }
    }
    // 最終行のデータを保存する
    if (!isReadingName) {
        dataList.push_back(data);
        result[name] = dataList;
    }
 
    FileRead_close(handle);
    return result;
}

void load_img(char par1[255]){
	char set0[255] = {"img/"};
	char set1[255] = {"img/"};
	strcat(set0,par1);
	strcat(set1,par1);
	strcat(set1,"/");
//カット
	//
	
	strcat(set1,par1);
	strcat(set1,".txt");

	bool readError = false;
    std::string errorMessage = "";
    std::vector<std::string> hensuu; // 「aaa = 31,14 等の変数を分割させて変数を保存する」に使用する変数
    std::map<std::string, std::vector<std::string> > dataFromTextFile;
    try {
        dataFromTextFile = readText(par1);
    } catch (std::string e) {
        errorMessage = e;
        readError = true;
    }


	if (dataFromTextFile.find("BackButton_Pos") != dataFromTextFile.end()) {
		hensuu = dataFromTextFile["BackButton_Pos"];
        btn[0][0] = (int)atoi((char *)hensuu[0].c_str());
        btn[0][1] = (int)atoi((char *)hensuu[1].c_str());
    }if (dataFromTextFile.find("PlayButton_Pos") != dataFromTextFile.end()) {
		hensuu = dataFromTextFile["PlayButton_Pos"];
        btn[1][0] = (int)atoi((char *)hensuu[0].c_str());
        btn[1][1] = (int)atoi((char *)hensuu[1].c_str());
    }if (dataFromTextFile.find("NextButton_Pos") != dataFromTextFile.end()) {
		hensuu = dataFromTextFile["NextButton_Pos"];
        btn[2][0] = (int)atoi((char *)hensuu[0].c_str());
        btn[2][1] = (int)atoi((char *)hensuu[1].c_str());
    }
	
}

かずま

Re: ファイルを読み込んで変数に入れたり再生する

#11

投稿記事 by かずま » 10年前

sscanf を使ってみました。書式の中のスペースは重要です。

コード:

#include <DxLib.h>
#include <stdio.h>   // sscanf

const char * readText(const char *fileName, int btn[3][2])
{
    int handle = FileRead_open(fileName, FALSE);
    if (handle == -1) return "FileRead_open error";
 
    char buf[256];
    while (FileRead_gets(buf, sizeof buf, handle) != -1) {
        int x, y, n;
        if (sscanf(buf, " BackButton_Pos =%d ,%d", &x, &y) == 2)
            btn[0][0] = x, btn[0][1] = y;
        else if (sscanf(buf, " PlayButton_Pos =%d ,%d", &x, &y) == 2)
            btn[1][0] = x, btn[1][1] = y;
        else if (sscanf(buf, " NextButton_Pos =%d ,%d", &x, &y) == 2)
            btn[2][0] = x, btn[2][1] = y;
    }
    FileRead_close(handle);
    return "";
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK);

    int btn[3][2];
    const char *errorMessage = readText("par1.txt", btn);

    while (!ScreenFlip() && !ProcessMessage() && !ClearDrawScreen()) {
        if (errorMessage[0])
            DrawFormatString(20, 20, GetColor(255, 0, 0), "エラー発生 : %s", errorMessage);
        else {
            int ypos = 20;
            for (int i = 0; i < 3; i++) {
                DrawFormatString(20, ypos, GetColor(255, 255, 255), "btn[%d]: (%d, %d)",
                    i, btn[i][0], btn[i][1]);
                ypos += 20;
            }
        }
    }
    DxLib_End();
    return 0;
}
入力ファイル par1.txt

コード:

BackButton_Pos = 31,14
PlayButton_Pos = 51,14
NextButton_Pos = 71,14

かずま

Re: ファイルを読み込んで変数に入れたり再生する

#12

投稿記事 by かずま » 10年前

かずま さんが書きました:sscanf を使ってみました。書式の中のスペースは重要です。
訂正です。
7行目: if (handle == -1) を、if (handle == 0) に。
11行目: int x, y, n; を、 int x, y; に。
20行目: return ""; を、 return NULL; に。
31行目: if (errorMessage[0]) を、if (errorMessage) に。

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

Re: ファイルを読み込んで変数に入れたり再生する

#13

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

DELTA-Ⅲ さんが書きました:組み込もうとしたら変数に変化がないのかうまくいかず、
わからない状態です。どこがいけないでしょうか。
適当にコードを補完して試したところ、Xキーを押すと正常にbtnの値が更新されるようでした。
何がどううまくいかないのでしょうか?(どうなってほしいのが、実行するとこういうようになってしまう、のように書いていただけるとわかりやすいです)

main.cpp

コード:

#include "GV.h"

int btn[3][2];

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
	if (ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() != 0) return -1;
	SetDrawScreen(DX_SCREEN_BACK);

	bool xFlag = false;
	int loadDisplay = 0;

	while (ProcessMessage() == 0 && ClearDrawScreen() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) {

		if (CheckHitKey(KEY_INPUT_X) == 1) {
			if (!xFlag) {
				char hoge[255] = "input.txt";
				load_img(hoge);
				loadDisplay = 255;
			}
			xFlag = true;
		} else {
			xFlag = false;
		}

		if (loadDisplay > 0) {
			DrawString(50, 300, "Load!", GetColor(loadDisplay, loadDisplay, loadDisplay));
			loadDisplay -= 10;
		}

		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 2; j++) {
				DrawFormatString(50 + j * 50, 50 + i * 50, GetColor(255, 255, 255), "%d", btn[i][j]);
			}
		}

		ScreenFlip();
	}

	DxLib_End();
	return 0;
}
GV.h

コード:

#ifndef GV_H_GUARD_00FD7528_9AB7_406D_B09E_E96C07ADEEDE
#define GV_H_GUARD_00FD7528_9AB7_406D_B09E_E96C07ADEEDE

#include <DxLib.h>

void load_img(char par1[255]);
extern int btn[3][2];

#endif
no10.cpp
(No: 10で提示されたコードそのまま)

input.txt

コード:

BackButton_Pos = 346,765
PlayButton_Pos = 333,634
NextButton_Pos = 1234,5678
添付ファイル
test10.zip
テスト用データ一式
(2.17 MiB) ダウンロード数: 167 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

DELTA-Ⅲ
記事: 21
登録日時: 11年前

Re: ファイルを読み込んで変数に入れたり再生する

#14

投稿記事 by DELTA-Ⅲ » 10年前

>>みけCATさん、かずまさん、
コードありがとうございます、ただファイル名が違っていただけみたいです。すみません。
おまけにbtnと言う変数が何故かbtn[1][(0または1)]が使えなくなる事態で分からなかったみたいです。
(btn[1][(0または1)]の事はまだ解決してないですが・・・)
しかし後回しにしたFindFirstFileの使い方が分からないです。
教えてくれますか、お願いします。

あごみつ
記事: 17
登録日時: 10年前

Re: ファイルを読み込んで変数に入れたり再生する

#15

投稿記事 by あごみつ » 10年前

まず、リファレンスを見ましょう(既にご覧になっていたらすみません)
FindFirstFile 関数 - MSDN
それでわからなかったら他の情報も探してみましょう(既に探していたらすみません)
FindFirstFile - Google 検索

たいていわかるはずです

本題ですが、どうやらあるディレクトリの中のファイルを列挙して読み込みたいようなので、
FindFirstFile, FindNextFile, FindCloseを使います

かなり適当に書きましたが、見つけたファイルを全部LoadSoundMemしてその戻り値をstd::unordered_map<std::string, int>に格納してます

コード:

#include <unordered_map>
#include <string>
#include <algorithm>

#include <windows.h>
#include <DxLib.h>

// ファイルパスからディレクトリ名を抽出
auto path2dir(std::string const &path)
{
	std::string::size_type pos = std::max<signed>(path.find_last_of('/'), path.find_last_of('\\'));
	return (pos == std::string::npos) ? std::string{} : path.substr(0, pos + 1);
}

// filename は検索したいファイルが満たす条件
// 例えば "sound/*.mp3" なんかを入れる
auto loadSoundFiles(char *filename)
{
	std::unordered_map<std::string, int> soundFiles; // こいつがこの関数の戻り値
	auto dirname = path2dir(filename);

	// 条件を満たすファイルが見つかった場合、こいつにそのファイルの情報が格納される
	WIN32_FIND_DATAA fileInfo;

	// 最初に条件を満たすファイルを検索
	auto handle = FindFirstFileA(filename, &fileInfo);
	if (handle == INVALID_HANDLE_VALUE) {
		// 条件を満たすファイルが一つも見つからない
	}

	do {
		soundFiles[fileInfo.cFileName] = LoadSoundMem(dirname + fileInfo.cFileName);
	} while (FindNextFileA(handle, &fileInfo)); // 次の条件を満たすファイルを検索

	// 検索を終了する
	FindClose(handle);

	return std::move(soundFiles);
}
DXライブラリは使ったことがないのですが、リファレンスを眺めた限りでは、これで動きそうです
駄目でしたら再度ご報告ください

PlaySoundMemでtest.mp3を再生したい時は

コード:

auto mp3Files = loadSoundFiles("sound/*.mp3");
auto id = mp3Files["test.mp3"];
PlaySoundMem(id, DX_PLAYTYPE_NORMAL, TRUE);
とすれば良いはずです

DELTA-Ⅲ
記事: 21
登録日時: 11年前

Re: ファイルを読み込んで変数に入れたり再生する

#16

投稿記事 by DELTA-Ⅲ » 10年前

あごみつ さんが書きました:まず、リファレンスを見ましょう(既にご覧になっていたらすみません)
FindFirstFile 関数 - MSDN
それでわからなかったら他の情報も探してみましょう(既に探していたらすみません)
FindFirstFile - Google 検索

たいていわかるはずです

本題ですが、どうやらあるディレクトリの中のファイルを列挙して読み込みたいようなので、
FindFirstFile, FindNextFile, FindCloseを使います
返信ありがとうございます。
リファレンスと検索はしましたが中々いいのもがありませんでした。

またコードにエラーがあるみたいで、「'auto'関数には後続の戻り値が必要です」と表示されています。

あごみつ
記事: 17
登録日時: 10年前

Re: ファイルを読み込んで変数に入れたり再生する

#17

投稿記事 by あごみつ » 10年前

修正しました
再度お試しください

コード:

#include <unordered_map>
#include <string>
#include <algorithm>
 
#include <windows.h>
#include <DxLib.h>
 
// ファイルパスからディレクトリ名を抽出
std::string path2dir(std::string const &path)
{
    std::string::size_type pos = std::max<signed>(path.find_last_of('/'), path.find_last_of('\\'));
    return (pos == std::string::npos) ? std::string() : path.substr(0, pos + 1);
}
 
// filename は検索したいファイルが満たす条件
// 例えば "sound/*.mp3" なんかを入れる
std::unordered_map<std::string, int> loadSoundFiles(char *filename)
{
    std::unordered_map<std::string, int> soundFiles; // こいつがこの関数の戻り値
    std::string dirname = path2dir(filename);
 
    // 条件を満たすファイルが見つかった場合、こいつにそのファイルの情報が格納される
    WIN32_FIND_DATAA fileInfo;
 
    // 最初に条件を満たすファイルを検索
    HANDLE handle = FindFirstFileA(filename, &fileInfo);
    if (handle == INVALID_HANDLE_VALUE) {
        // 条件を満たすファイルが一つも見つからない
    }
 
    do {
        soundFiles[fileInfo.cFileName] = LoadSoundMem((dirname + fileInfo.cFileName).c_str());
    } while (FindNextFileA(handle, &fileInfo)); // 次の条件を満たすファイルを検索
 
    // 検索を終了する
    FindClose(handle);
 
    return std::move(soundFiles);
}

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

Re: ファイルを読み込んで変数に入れたり再生する

#18

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

あごみつ さんが書きました:

コード:

    // 最初に条件を満たすファイルを検索
    HANDLE handle = FindFirstFileA(filename, &fileInfo);
    if (handle == INVALID_HANDLE_VALUE) {
        // 条件を満たすファイルが一つも見つからない
    }
ここで「条件を満たすファイルが一つも見つからない」時に何もしていないですが、即soundFilesを返すなどのエラー処理が必要ではないのでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

あごみつ
記事: 17
登録日時: 10年前

Re: ファイルを読み込んで変数に入れたり再生する

#19

投稿記事 by あごみつ » 10年前

みけCAT さんが書きました:
あごみつ さんが書きました:

コード:

    // 最初に条件を満たすファイルを検索
    HANDLE handle = FindFirstFileA(filename, &fileInfo);
    if (handle == INVALID_HANDLE_VALUE) {
        // 条件を満たすファイルが一つも見つからない
    }
ここで「条件を満たすファイルが一つも見つからない」時に何もしていないですが、即soundFilesを返すなどのエラー処理が必要ではないのでしょうか?
まったくもっておっしゃる通りです
手元にDxLibがない環境で、ろくにテストもせずに提示した俺の落ち度です

申し訳ありません

それと、soundディレクトリはカレントのディレクトリに配置してください
恐らく実行ファイルを生で起動した場合は実行ファイルの位置がカレントに、MSVC上で実行した場合はプロジェクトファイルの位置がカレントになるかと思います

DELTA-Ⅲ
記事: 21
登録日時: 11年前

Re: ファイルを読み込んで変数に入れたり再生する

#20

投稿記事 by DELTA-Ⅲ » 10年前

>>みけCATさん、あごみつ さん、
ありがとうございます。
少し改変してはいますが無事に読み込んでいます。
後は何とか出来そうです。

閉鎖

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