フォルダの読み込み
-
御津凪
Re:フォルダの読み込み
Windows 環境であれば、 Windows API の FindFirstFile と FindNextFile を使って
フォルダ内のファイルやフォルダを検索することが出来ます。
簡単ながらコードを書いてみました。
ANSI・UNICODE両ビルド可、クロスコンパイル(Windowsのみ)に対応してみました。
(これを書いたPC環境にチェックするためのコンパイラが無いので、正しくビルド・実行できるかは分かりません。あしからず^^;)
定義マクロはバッサリ切って直接書けば良いです。
フォルダ内のファイルやフォルダを検索することが出来ます。
簡単ながらコードを書いてみました。
ANSI・UNICODE両ビルド可、クロスコンパイル(Windowsのみ)に対応してみました。
(これを書いたPC環境にチェックするためのコンパイラが無いので、正しくビルド・実行できるかは分かりません。あしからず^^;)
#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); // 検索ハンドルを閉じる
}
環境が限定的なら、定義マクロはバッサリ切って直接書けば良いです。
-
lbfuvab
Re:フォルダの読み込み
うちの環境(WinXP,VC++2008EE)と仮定しています。
ディレクトリの選択 :SHBrowseForFolder、SHGetPathFromIDList、CoTaskMemFree
ディレクトリ内の検索:SetCurrentDirectory、GetCurrentDirectry、FindFirstFile、FindNextFile
MP3の再生? :Dxライブラリ or MCI
↑のあたりですかね。
ディレクトリの選択 :SHBrowseForFolder、SHGetPathFromIDList、CoTaskMemFree
ディレクトリ内の検索:SetCurrentDirectory、GetCurrentDirectry、FindFirstFile、FindNextFile
MP3の再生? :Dxライブラリ or MCI
↑のあたりですかね。
-
ポリ
Re:フォルダの読み込み
回答ありがとうございます。
環境はWindowsなのですが、DXライブラリのみでの作成で
WinAPIについては知識不足で・・・
せっかく回答をいただいたので、それを元にいろいろと調べてみます。
ちなみにDXライブラリとC言語だけでは実装は不可なのですか?
現在テキスト形式のデータに曲名を追加して読み込ませる方法も考えて
いるのですが・・・
できればフォルダの列挙をしてみたかったので><
環境はWindowsなのですが、DXライブラリのみでの作成で
WinAPIについては知識不足で・・・
せっかく回答をいただいたので、それを元にいろいろと調べてみます。
ちなみにDXライブラリとC言語だけでは実装は不可なのですか?
現在テキスト形式のデータに曲名を追加して読み込ませる方法も考えて
いるのですが・・・
できればフォルダの列挙をしてみたかったので><
-
Mist
Re:フォルダの読み込み
> ちなみにDXライブラリとC言語だけでは実装は不可なのですか?
無理です。
DXライブラリはDirectXを簡易に使えるようにするためのライブラリですからフォルダに関する機能は対象外です。
また、フォルダの管理はOSに依存するところになりますのでC言語にはそのような関数はありません。
無理です。
DXライブラリはDirectXを簡易に使えるようにするためのライブラリですからフォルダに関する機能は対象外です。
また、フォルダの管理はOSに依存するところになりますのでC言語にはそのような関数はありません。
-
ポリ
Re:フォルダの読み込み
早い回答ありがとうございます。
やはりWinAPIを使わないとフォルダの列挙は無理ですか・・・
ゲームにコモンダイアログ等を出したくないので、
DXライブラリのFileRead等の関数を使ってテキストデータを一行ずつ
取り出してみようと思います。
回答してくださった皆様ありがとうございます。
やはりWinAPIを使わないとフォルダの列挙は無理ですか・・・
ゲームにコモンダイアログ等を出したくないので、
DXライブラリのFileRead等の関数を使ってテキストデータを一行ずつ
取り出してみようと思います。
回答してくださった皆様ありがとうございます。
-
Mist
Re:フォルダの読み込み
_findfirstはCRTに含まれますのでWindowsAPIではないですね。
ポリさんの言うところのC言語を私は「ANSI C」と解釈しましたのでCRTは含んでいないです。
ポリさんの言うところのC言語を私は「ANSI C」と解釈しましたのでCRTは含んでいないです。
-
non
Re:フォルダの読み込み
ポリさんが何をしたいのか、理解出来ていないし、DXライブラリも使ったことがないので
わからないのですが、環境に依存してはいけないのですか。
windowsでもUnixでもマックでも動くソフトを作りたいのでしょうか?
わからないのですが、環境に依存してはいけないのですか。
windowsでもUnixでもマックでも動くソフトを作りたいのでしょうか?
-
Mist
Re:フォルダの読み込み
ん~、私の回答悪かったでしょうか?
ポリさんはWinAPIはわかんないからDXライブラリ+C言語だけで出来ないかどうかを質問されていましたので「無理(だから勉強してね)」と回答しただけですけど。
環境依存は使いたくないとは一言も言っておられないですね。
> ゲームにコモンダイアログ等を出したくないので、
この回答から察するに、「WinAPIを使用する」=「何かダイアログが出る」と勘違いされているのかな?
ポリさんはWinAPIはわかんないからDXライブラリ+C言語だけで出来ないかどうかを質問されていましたので「無理(だから勉強してね)」と回答しただけですけど。
環境依存は使いたくないとは一言も言っておられないですね。
> ゲームにコモンダイアログ等を出したくないので、
この回答から察するに、「WinAPIを使用する」=「何かダイアログが出る」と勘違いされているのかな?
-
non
Re:フォルダの読み込み
>この回答から察するに、「WinAPIを使用する」=「何かダイアログが出る」と勘違いされているのかな?
よく読めば、コモンダイアログがどうとかって書いてありますね。
それなら、コモンダイアログは出ません。ってことでいいでしょうか。
_findfirstを使えば、フォルダの一覧も作れるし、再帰呼び出しにすれば
フォルダの中の子フォルダのファイル中身もすべて表示できます。
よく読めば、コモンダイアログがどうとかって書いてありますね。
それなら、コモンダイアログは出ません。ってことでいいでしょうか。
_findfirstを使えば、フォルダの一覧も作れるし、再帰呼び出しにすれば
フォルダの中の子フォルダのファイル中身もすべて表示できます。
-
御津凪
Re:フォルダの読み込み
> _findfirstを使えば、フォルダの一覧も作れるし、再帰呼び出しにすれば
> フォルダの中の子フォルダのファイル中身もすべて表示できます。
こちらの方が32/64bit環境に対応している分、良いかもしれませんね。
WinAPI とほぼ同じ使い方ですし。
せっかくなので、_findfirst 関数使用バージョンを書いてみました。
WinAPI を使用しないため、日本語対応のための処理が入っています。
こちらの方が WinAPI を使用しない分、余計なものを定義されずにすみますね。
(これも上記で書いた環境と同じところで書いたので以下略。)
> フォルダの中の子フォルダのファイル中身もすべて表示できます。
こちらの方が32/64bit環境に対応している分、良いかもしれませんね。
WinAPI とほぼ同じ使い方ですし。
せっかくなので、_findfirst 関数使用バージョンを書いてみました。
WinAPI を使用しないため、日本語対応のための処理が入っています。
#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 版と比べるとコードが若干増えていますが、こちらの方が WinAPI を使用しない分、余計なものを定義されずにすみますね。
(これも上記で書いた環境と同じところで書いたので以下略。)
-
GPGA
Re:フォルダの読み込み
とっても手抜き
#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;
}
} -
GPGA
Re:フォルダの読み込み
>御津凪さん
素朴なことなんですが、S-JISで '.'(0x2e) が2バイト目にくる2バイト文字って存在しなくないですか?
Windows XP、VS2008にて確認
素朴なことなんですが、S-JISで '.'(0x2e) が2バイト目にくる2バイト文字って存在しなくないですか?
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;
} Windows XP、VS2008にて確認
-
御津凪
Re:フォルダの読み込み
> 素朴なことなんですが、S-JISで '.'(0x2e) が2バイト目にくる2バイト文字って存在しなくないですか?
そういえばそうですね。
2バイト目判定無くても確かに正常に動作しますね。
そういえばそうですね。
2バイト目判定無くても確かに正常に動作しますね。
// 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);
}
判定を省いたもの&省コード化しておきます。