Từ 1 tới 8 trên tổng số 8 kết quả

Đề tài: Chương trình đệ quy này có lỗi gì?!!

  1. #1
    Ngày gia nhập
    11 2007
    Bài viết
    20

    Post Chương trình đệ quy này có lỗi gì?!!

    Em viết một chương trình đệ quy để duyệt 1 thư mục như sau:

    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;
    }
    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:
     if (GetLastError()==ERROR_NO_MORE_FILES)
       {
      //MessageBox(0,TEXT(dd),TEXT(dd),0);
      
      return ;
    }
    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.

    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.

  2. #2
    Ngày gia nhập
    11 2007
    Bài viết
    20

    Hic hic. Có ai giúp mình với ko?

  3. #3
    Ngày gia nhập
    11 2007
    Bài viết
    20

    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 đỡ!!!!

  4. #4
    Ngày gia nhập
    09 2006
    Bài viết
    711

    Khi gọi 1 hàm API, GetLastError sẽ thay đỗi.

  5. #5
    Ngày gia nhập
    11 2007
    Bài viết
    20

    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 đỡ

  6. #6
    Ngày gia nhập
    09 2006
    Bài viết
    16

    Mặc định Chương trình đệ quy này có lỗi gì?!!

    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

  7. #7
    Ngày gia nhập
    11 2007
    Bài viết
    20

    cảm ơn bạn coolkit nhiều nha

  8. #8
    Ngày gia nhập
    12 2007
    Bài viết
    2

    lần đầu thấy duyệt file dùng GetLastError, mình hay dùng kiểu khác ví dụ sau:

    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
    }
    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)
    Đã đượ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

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn