フォルダの読み込み
Posted: 2009年1月08日(木) 11:25
音楽ゲームを作成しているのですが、曲の追加をする時今はMP3までのパスを指定しメモリに読み込ませ
再生しています。
曲の追加をする際に、STEPMANIAのようにフォルダに曲を追加して曲一覧として表示、再生させる方法は
あるのでしょうか?
再生しています。
曲の追加をする際に、STEPMANIAのようにフォルダに曲を追加して曲一覧として表示、再生させる方法は
あるのでしょうか?
#include <windows.h>
#include <shlwapi.h>
// #include <tchar.h> // 必要かも。
// shlwapi.lib をリンクする必要あり
// tcsicmp の定義マクロ
#ifndef tcsicmp
#ifdef _tcsicmp
#define tcsicmp _tcsicmp
#else
#endif
#if defined(UNICODE) || defined(_UNICODE)
#ifdef _MSC_VER
#define tcsicmp(a,b) _wcsicmp(a,b)
#else
#define tcsicmp(a,b) wcsicmp(a,b)
#endif
#else
#ifdef _MSC_VER
#define tcsicmp(a,b) _stricmp(a,b)
#else
#define tcsicmp(a,b) stricmp(a,b)
#endif
#endif
#endif
#endif
// 検索処理関数
void SearchMP3File( LPCTSTR str ){
WIN32_FIND_DATA wfd;
HANDLE h = FindFirstFile(str,&wfd);
if(h == INVALID_HANDLE_VALUE){ // パスが存在しない
return;
}
do{
if((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 && // パスがフォルダでないもので、
tcsicmp(PathFindExtension(wfd.cFileName),TEXT(".mp3")) == 0) // 拡張子が".mp3"のファイル
{
TCHAR buf[PATH_MAX];
// 検索ディレクトリパスとファイルパスを結合
PathCombine(buf,str,wfd.cFileName);
// ここで buf には、MP3ファイルへのパスが入った状態。
// 後は何らかの処理をここに入れる
}
}while(FindNextFile(h,&wfd)); // 次のパスを検索
FindClose(h); // 検索ハンドルを閉じる
}
環境が限定的なら、#include <io.h>
#include <tchar.h>
// WinAPI PathFindExtension 関数の代替
static _TCHAR* GetPathExtension( _TCHAR* path ){
_TCHAR* i;
if(!path) return NULL;
for(i = path + _tcslen(path) - 1;i >= path;--i){
#ifdef _UNICODE
// UNICODE 用処理
if(*i == L'.'){
break; // こっちだと簡単
}
#else
// ANSI(ShiftJIS) 用処理
if(*i == '.'){
_TCHAR c = *(i-1);
if(*i == path || !((0x81 <= c && c <= 0x9F) || (0xE0 <= c && c <= 0xEF))){
break; // こちらだと一つ前のバイト文字をチェックする必要がある
}
}
#endif
}
if(i < path) return path + _tcslen(path);
return i;
}
// 検索処理関数
void SearchMP3File( const _TCHAR* str ){
_finddata_t fd;
intptr_t h = _tfindfirst(str,&fd);
if(h == -1){ // パスが存在しない
return;
}
do{
if((fd.attrib & _A_SUBDIR) == 0 && // パスがフォルダでないもので、
_tcsicmp(GetPathExtension(fd.name),_T(".mp3")) == 0) // 拡張子が".mp3"のファイル
{
_TCHAR buf[_MAX_PATH];
// 検索ディレクトリパスとファイルパスを結合
_tcscpy_s(buf,_MAX_PATH,str);
_tcscat_s(buf,_MAX_PATH,_T('\\'));
_tcscat_s(buf,_MAX_PATH,fd.name);
// ここで buf には、MP3ファイルへのパスが入った状態。
// 後は何らかの処理をここに入れる
}
}while(_findnext(h,&fd) == 0); // 次のパスを検索
_findclose(h); // 検索ハンドルを閉じる
}
上記で書いた WinAPI 版と比べるとコードが若干増えていますが、#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
/*!
* @brief 指定したフォルダ内のmp3ファイル名をリストに出力
*
* @param outList 出力先を指定します。
* @param directory ディレクトリを指定します。
* @param tempListName 一時的なリストファイル名を指定します。
*
* @return true:正常終了 false:異常終了
*/
bool GetFileList(std::vector<std::string>& outList, const char* szDirectory, const char* tempListName)
{
char s[256];
sprintf(s, "dir /b %s\\*.mp3 > %s", szDirectory, tempListName);
system(s);
FILE* fp = fopen(tempListName, "r");
while (fgets(s, sizeof(s), fp) != NULL) {
s[strlen(s) - 1] = '\0';
outList.push_back(s);
}
fclose(fp);
sprintf(s, "del %s", tempListName);
system(s);
return true;
}
int main()
{
std::vector<std::string> fileList;
// カレントディレクトリを検索し、検索した結果を一時的にlist.txtに書き込む
GetFileList(fileList, ".c", "list.txt");
std::vector<std::string>::iterator it = fileList.begin();
for (; it != fileList.end(); ++it) {
std::cout << *it << std::endl;
}
} int main()
{
unsigned char c = '.';
for (unsigned char i = 0x81; i <= 0x9F; ++i) {
printf("%c%c\n", i, c);
}
for (unsigned char i = 0xE0; i <= 0xEF; ++i) {
printf("%c%c\n", i, c);
}
return 0;
} // WinAPI PathFindExtension 関数の代替
static _TCHAR* GetPathExtension( _TCHAR* path ){
_TCHAR* i;
if(!path) return NULL;
for(i = path + _tcslen(path) - 1;i >= path;--i){
if(*i == _T('.')) return i;
}
return path + _tcslen(path);
}
判定を省いたもの&省コード化しておきます。