Hic hic. Có ai giúp mình với ko?
Em viết một chương trình đệ quy để duyệt 1 thư mục như sau:
Chức năng của chương trình là tìm kiếm tất cả những thư mục con và file của ổ D. Sau đó ẩn các file đi. Nhưng có một điều lạ xảy ra là :Code:#include <windows.h> #include <winbase.h> #include <stdio.h> char bs[]="\\*.*"; void scandir(char *d) // Hàm đệ quy duyệt thư mục { /* Các biến sử dụng trong chương trình */ int first=1; // Kiểm tra có phải file đầu tiên? HANDLE hwnd; // 1 định danh nhận giá trị của hàm FindFirsFile, và là đối số cho hàm FindNextFile WIN32_FIND_DATA finddata; // Cấu trúc dùng trong hàm FindFirst, và FindNex char dd[100], ddd[100],file[200]; // Các biến lưu đường dẫn file sprintf(dd,"%s%s",d,bs); // Nối 2 chuỗi d, bs thành chuỗi dd /* ĐỆ QUY */ while (1) { /* Kiểm tra xem có phải file đầu tiên được tìm thấy ko? */ if(first==1) // Nếu đúng là file đầu tiên { hwnd=FindFirstFile(dd,&finddata); first=0; } else //Ngược lại FindNextFile(hwnd, &finddata); if(finddata.cFileName[0]=='.') // Nếu là thư mục . và .. thì bỏ qua { continue; } if (GetLastError()==ERROR_NO_MORE_FILES) // Nếu là file cuối cùng { //MessageBox(0,TEXT(dd),TEXT(dd),0); return ; } // Kiểm tra thuộc tính có file là thư mục không? if(finddata.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY) { sprintf(ddd,"%s\\%s",d,finddata.cFileName); /*Gọi lại hàm để quy*/ scandir(ddd); } else { sprintf(file,"%s\\%s",d,finddata.cFileName); // Thay đổi thuộc tính thư mục SetFileAttributes(file,FILE_ATTRIBUTE_HIDDEN); } } } int main () { DWORD oldatrib; HANDLE hwnd; WIN32_FIND_DATA finddata; scandir("d:"); return 0; }
nếu khối lệnh này bỏ dòng MessageBox(0,TEXT(dd),TEXT(dd),0); thì nó ko thể duyệt hết tất cả các thư mục của ổ D mà chỉ duyệt được 1 thư mục trong ổ đó sau đó ẩn các file trong thư mục này và chương trình kết thúc. Còn nếu dòng MessageBox(0,TEXT(dd),TEXT(dd),0); này được thêm vào thì chương trình lại duyệt được tất cả các file theo đúng thuật toán đệ quy em đã trình bày.Code:if (GetLastError()==ERROR_NO_MORE_FILES) { //MessageBox(0,TEXT(dd),TEXT(dd),0); return ; }
Vậy thì cho em hỏi tại sao lại như thế. Nếu ko có dòng này thì ko ảnh hưởng gì đến chương trình cả. Nhưng tại sao ko có nó thì lại ko làm được. Em viết trên trình dịch Dev C++.
Rất mong được mọi người giúp đỡ.!!!
;-0
Đã được chỉnh sửa lần cuối bởi chaien281985 : 01-01-2008 lúc 10:32 AM. Lý do: Cho code vào tag code. Nhắc nhở tác giả cho code vào tag, và đọc nội quy tham gia.
Hic hic. Có ai giúp mình với ko?
Thật sự là em bó tay với bài này luôn. Ko hiểu tại sao khi thêm cái dòng MessageBox(0,TEXT(dd),TEXT(dd),0);
vào trong
if (GetLastError()==ERROR_NO_MORE_FILES) // Nếu là file cuối cùng
{
MessageBox(0,TEXT(dd),TEXT(dd),0);
return ;
}
thì lại có thể đệ quy được còn ko thêm vào thì ko tài nào đệ quy được. Ko tin bác nào cứ paste cái bài của em vào VS C++ hoặc Dev C++ chạy thử xem. Đây ko phải là lỗi cú pháp nên em ko tài nào tìm ra nguyên nhân tại sao?
Rất mong được các bạn giúp đỡ!!!!
Khi gọi 1 hàm API, GetLastError sẽ thay đỗi.
Vậy có nghĩa là nếu mình thay hàm MessageBox bằng một hàm API khác thì cũng được đúng ko?
Nhưng tại sao lại như thế? Về mặt thuật toán thì thuật toán đệ quy của mình ko hề sai? Làm thế nào để giải quyết vấn đề này?
Ai có thể viết lại thuật toán đệ quy thư mục cho mình ko?
Rất mong được giúp đỡ
bạn down cái này về. Có thể nó sẽ giúp ích cho bạn.
http://216.240.157.23/~d2tgroup/upli...load.php?id=83
good luck
nothing is impossible
cảm ơn bạn coolkit nhiều nha
lần đầu thấy duyệt file dùng GetLastError, mình hay dùng kiểu khác ví dụ sau:
Lưu ý: Vui lòng để code trong tag code. Chi tiết vui lòng tham khảo Nội quy hoặc Hỏi/Đáp trên thanh công cụ (Nhắc nhở bởi Dreaminess)Code:int SearchDirectory(const std::string &refcstrRootDirectory,const std::string &refcstrExtension) { int iCount = 0; std::string strFilePath; // Filepath std::string strPattern; // Pattern HANDLE hFile; // Handle to file WIN32_FIND_DATA FileInformation; // File information strPattern = refcstrRootDirectory + "\\*." + refcstrExtension; hFile = ::FindFirstFile(strPattern.c_str(), &FileInformation); if(hFile != INVALID_HANDLE_VALUE) { do { if(FileInformation.cFileName[0] != '.') { strFilePath.erase(); strFilePath = refcstrRootDirectory + "\\" + FileInformation.cFileName; if(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // Search subdirectory int iRC = SearchDirectory(strFilePath, refcstrExtension); if(iRC != -1) iCount += iRC; else return -1; } else { // HANDLE YOUR ARRAY FILE STORE AND FILE RENAME STUFF HERE <====== // Increase counter ++iCount; } } } while(::FindNextFile(hFile, &FileInformation) == TRUE); // Close handle ::FindClose(hFile); } return iCount; // return filecount }
Đã được chỉnh sửa lần cuối bởi Kevin Hoang : 11-01-2008 lúc 12:35 AM. Lý do: code vào tag