2010-01-10 39 views
6

Cuối cùng, tôi muốn đi qua các tệp và thư mục con của thư mục và viết một cái gì đó cho tất cả các tệp tôi thấy có phần mở rộng nhất định (.wav trong trường hợp của tôi). khi looping làm thế nào để tôi biết nếu mục tôi đang ở là một thư mục?Làm thế nào để đệ quy các thư mục đi qua trong C trên Windows

+0

thư mục Vượt qua được hệ điều hành phụ thuộc, vì vậy bạn có thể cần phải cho chúng tôi biết những gì hệ điều hành bạn đang sử dụng. Có một số thư viện độc lập với hệ điều hành. Nếu bạn đang sử dụng một trong số họ, chúng tôi sẽ cần biết cái nào để đưa ra câu trả lời hay. –

+0

Đây có phải là một nền tảng UNIX-y (Mac, v.v.) hay Windows, hay cái gì khác hoàn toàn? Nhiều nền tảng sẽ hỗ trợ các tiêu chuẩn POSIX (http://robot.mbhs.edu/wordpress/2009/how-to-get-a-directory-listing-in-c-posix/), nhưng cũng thường sẽ có cách riêng để làm điều này, đặc biệt là Windows (FindFirstFile/FindNextFile) –

+0

Tôi vẫn không nhận được điều này để làm việc như thế nào tôi muốn. FindFirstFile là xuất ra tên của thư mục mà tôi đang ở, không phải là tập tin đầu tiên trong thư mục nếu tôi rời khỏi dấu /. Nếu tôi đặt dấu/nó cho tôi một tên tập tin lạ (aaaaa-LIBVC ...).Ngoài ra, cả hai lần FindNextFile sẽ không trả lại bất kỳ giá trị nào ở tất cả các số – pmilb

Trả lời

0

opendir và readdir (trên unix), đây là một ví dụ:

http://opengroup.org/onlinepubs/007908775/xsh/readdir.html

hoặc FindFirstFile trên cửa sổ

bạn cũng có thể sử dụng vỏ khá dễ dàng:

find . -name "*.wav" 

or 

ls **/*.wav (in zsh and newer bashes) 
+0

oops, quên nói rằng tôi cũng đang làm điều này trên windoze. – pmilb

3

Dựa về việc bạn đề cập đến số .wav, tôi sẽ đoán bạn đang viết mã cho Windows (có vẻ như là nơi *.wav tệp phổ biến nhất). Trong trường hợp này, bạn sử dụng FindFirstFileFindNextFile để chuyển các thư mục. Các cấu trúc này sử dụng cấu trúc WIN32_FIND_DATA có cấu trúc dwFileAttributes chứa các cờ cho biết các thuộc tính của tệp. Nếu dwAttributes & FILE_ATTRIBUTE_DIRECTORY khác không, bạn có tên của một thư mục.

+0

Vâng, tôi đang làm điều này trên Windows. C của tôi là thực sự gỉ, đã không được lập trình trong C cho một vài năm. Tôi đã cố gắng sử dụng dirent.h, nhưng tôi không nghĩ rằng nó cung cấp bất kỳ cách nào để nói nếu mục là một thư mục hay không. Không thể tìm thấy một ví dụ hay về FindFirstFile từ google – pmilb

+0

Trang này cho biết cách sử dụng chúng (trong VB, nhưng bản dịch sang C phải dài hơn hoặc ít hơn): http://support.microsoft.com/kb/185476. Lưu ý rằng bạn cũng có thể muốn suy nghĩ về cách bạn xử lý các nút nối NTFS, tức là có nên theo dõi chúng hay không và nếu bạn làm cách nào để tránh các vòng lặp vô tận. – Carsten

7

Đây là cách bạn làm điều đó (đây là tất cả từ bộ nhớ để có thể có sai sót):

void FindFilesRecursively(LPCTSTR lpFolder, LPCTSTR lpFilePattern) 
{ 
    TCHAR szFullPattern[MAX_PATH]; 
    WIN32_FIND_DATA FindFileData; 
    HANDLE hFindFile; 
    // first we are going to process any subdirectories 
    PathCombine(szFullPattern, lpFolder, _T("*")); 
    hFindFile = FindFirstFile(szFullPattern, &FindFileData); 
    if(hFindFile != INVALID_HANDLE_VALUE) 
    { 
     do 
     { 
      if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
      { 
       // found a subdirectory; recurse into it 
       PathCombine(szFullPattern, lpFolder, FindFileData.cFileName); 
       FindFilesRecursively(szFullPattern, lpFilePattern); 
      } 
     } while(FindNextFile(hFindFile, &FindFileData)); 
     FindClose(hFindFile); 
    } 

    // Now we are going to look for the matching files 
    PathCombine(szFullPattern, lpFolder, lpFilePattern); 
    hFindFile = FindFirstFile(szFullPattern, &FindFileData); 
    if(hFindFile != INVALID_HANDLE_VALUE) 
    { 
     do 
     { 
      if(!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 
      { 
       // found a file; do something with it 
       PathCombine(szFullPattern, lpFolder, FindFileData.cFileName); 
       _tprintf_s(_T("%s\n"), szFullPattern); 
      } 
     } while(FindNextFile(hFindFile, &FindFileData)); 
     FindClose(hFindFile); 
    } 
} 

Vì vậy, bạn có thể gọi đây là như

FindFilesRecursively(_T("C:\\WINDOWS"), _T("*.wav")); 

để tìm tất cả các định dạng * .wav tệp trong C: \ WINDOWS và các thư mục con của nó.

Về mặt kỹ thuật, bạn không phải thực hiện hai cuộc gọi FindFirstFile(), nhưng tôi thấy các chức năng khớp mẫu mà Microsoft cung cấp (ví dụ: PathMatchFileSpec hoặc bất kỳ thứ gì) không có khả năng như FindFirstFile(). Mặc dù cho "* .wav" nó có lẽ sẽ ổn thôi.

+0

@ Luke- Chức năng tuyệt vời. – Abhineet

+0

Cảm ơn! Bên cạnh một vài loại nhỏ, nó hoạt động rất tốt. –

+1

'Bên cạnh một số loại nhỏ, nó hoạt động tuyệt vời.' @NeilWeicher có một nút chỉnh sửa để bạn có thể khắc phục những lỗi chính tả nhỏ đó. – Synetech

1

Rất hữu ích. Tôi đã có, một ngăn xếp tràn vì nó luôn luôn thêm "." đến đường dẫn và quay trở lại cùng một đường dẫn = vòng lặp vô tận.

Thêm này giải quyết nó:

// found a subdirectory; recurse into it PathCombine(szFullPattern, lpFolder, FindFileData.cFileName); FindFilesRecursively(szFullPattern, lpPattern); if (FindFileData.cFileName[0] == '.') continue;

+0

Điều đó sẽ loại trừ * tất cả * thư mục bắt đầu bằng dấu chấm (bao gồm các thư mục ẩn đến từ hệ thống * nix). – Synetech

Các vấn đề liên quan