コードを左詰めで書いて、よくそれでプログラムが読めますね。
インデント(字下げ)するのは、プログラムの構造を明確にするためです。
コード:
#include <Windows.h>
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
string current = "C:\\Users\\";
char szDirectoryName[MAX_PATH];
int FindFile(string current);
int main()
{
FindFile(current);
return 0;
}
int FindFile(string current)
{
ofstream ofs("FileName.txt", ios::app);
WIN32_FIND_DATA date;
HANDLE handle = FindFirstFile(current.c_str(), &date);
if (handle == INVALID_HANDLE_VALUE)
cout << "ファイルなし(FindFirstFile)\n" << endl;
else {
for (;;) {
if ((strcmp(date.cFileName, ".") != 0)
&& (strcmp(date.cFileName, "..") != 0)) {
if (date.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
GetCurrentDirectory(MAX_PATH, szDirectoryName);
cout << "(DirectryName)" << szDirectoryName << endl;
current = current + "\\" + date.cFileName;
cout << "(current)" << current << endl;
FindFile(current);
} else {
cout << "(FileName)" << date.cFileName << endl;
ofs << date.cFileName << endl;
}
}
if (!FindNextFile(handle, &date)) {
if (GetLastError() == ERROR_NO_MORE_FILES) {
cout << "ファイルなし(FindNextFile)\n" << endl;
break;
}
break;
}
}
}
FindClose(handle);
ofs.close();
return 0;
}
if文や、forループがどこで始まってどこで終わっているのかがよくわかるでしょう。
次に ofstream を再帰関数の中にこんな風に書くと、おかしなことが起こります。
FindFile関数内の ofsオブジェクトは別々のものなので、バッファリングの
バッファもそれぞれが持っています。
例えば次のプログラムを試してみてください。
コード:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ofstream ofs1("abc.txt", ios::app);
ofs1 << "abc\n";
ofstream ofs2("abc.txt", ios::app);
ofs2 << "def\n";
ofstream ofs3("abc.txt", ios::app);
ofs3 << "ghi\n";
ofs3.close();
ofs2.close();
ofs1.close();
}
実行結果の abc.txt
ofs3.close() で "ghi\n" が出力された後に、
"def\n" や "abc\n" が追加されています。
元のプログラムの ofs はグローバルオブジェクトにするか、
あるいは、main のローカルオブジェクトにして、FindFile には
その参照を渡すようにしないといけないでしょう。
FindFirstFileをよく読んでください。
"C:\\Users\\" も "C:\\Users" もダメで、"C:\\Users\\*" としないと
ディレクトリの中のファイルは取得できないでしょう。
次のコードを参考に、もう一度挑戦してみてください。
コード:
#include <windows.h> // FindFirstFile, FindNextFile
#include <iostream> // cout
#include <string> // string
using namespace std;
int FindFile(string dir)
{
static string dot("."), dotdot("..");
WIN32_FIND_DATA data;
HANDLE handle = FindFirstFile((dir + "\\*").c_str(), &data);
if (handle == INVALID_HANDLE_VALUE)
cout << "FindFirstFile failed\n";
else {
do {
if (data.cFileName != dot && data.cFileName != dotdot) {
string path = dir + "\\" + data.cFileName;
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
FindFile(path);
else
cout << path << endl;
}
} while (FindNextFile(handle, &data));
FindClose(handle);
}
return 0;
}
int main()
{
FindFile("C:\\tmp\\java");
return 0;
}