2016-02-16 4 views
1

Я пытаюсь сохранить имя всех файлов txt в каталоге в строке и распечатать их. Мне нужно подсчитать количество txt-файлов в каталоге и затем распечатать имена. Часть счета работает, но я не могу заставить это имя работать. Я нашел несколько примеров, но они не работают в visual studio, и это то, что я использую.Список всех текстовых файлов в каталоге в C++

Вот мой код.

int main() { 

    bool x = true; 
    int i = 0; 

    wchar_t* file = L"../Menu/Circuitos/*.txt"; 
    WIN32_FIND_DATA FindFileData; 

    HANDLE hFind; 

    hFind = FindFirstFile(file, &FindFileData); 

    if (hFind != INVALID_HANDLE_VALUE) { 

     i++; 

     while ((x = FindNextFile(hFind, &FindFileData)) == TRUE) { 
      i++; 
     } 
    } 

    cout << "number of files " << i << endl; 

    return 0; 
} 
+1

Хлоп. Можете ли вы сделать «Ctrl + K», а затем «Ctrl + D» на свой код, а затем отправить его еще раз? – JesseTG

+0

Что именно вы подразумеваете под термином ** «Я не могу заставить имя работать» **? [WIN32_FIND_DATA] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa365740 (v = vs.85) .aspx) имеют 'cFileName'. Он пуст? BTW, вы должны проверить атрибуты файла для 'FILE_ATTRIBUTE_DIRECTORY' –

+0

, не следует ли это' '..// Меню // Circuitos // *. Txt" '? –

ответ

1

FindFirstFile уже имеет первую действительную ручку. Если вы сразу вызовете FindNextFile, тогда первый дескриптор будет потерян. Количество файлов в вашем примере будет неправильным.

Использование loop istead.

Кроме того, ручка, полученная из FindFirstFile должна быть закрыта с FindClose

HANDLE hFind; 
hFind = FindFirstFile(file, &FindFileData); 
if (hFind != INVALID_HANDLE_VALUE) 
{ 
    do { 
     wcout << FindFileData.cFileName << "\n"; 
     i++; 
    } while (FindNextFile(hFind, &FindFileData)); 
    FindClose(hFind); 
} 
cout << "number of files " << i << endl; 

Использованием std::vector и std::wstring для хранения элементов

#include <string> 
#include <vector> 

... 
std::vector<std::wstring> vs; 
HANDLE hFind; 
hFind = FindFirstFile(file, &FindFileData); 
if (hFind != INVALID_HANDLE_VALUE) 
{ 
    do { 
     vs.push_back(FindFileData.cFileName); 
    } while (FindNextFile(hFind, &FindFileData)); 
    FindClose(hFind); 
} 

std::cout << "count:" << vs.size() << "\n"; 
for (auto item : vs) 
    std::wcout << item << "\n"; 

Для некоторых старых компиляторов auto не может быть доступны, используйте этот вместо этого

for (int i = 0; i < vs.size(); i++) 
    std::wcout << vs[i] << "\n"; 

Примечание. Windows API работает с c-строками. Во многих случаях для получения массива символов вы должны использовать .c_str(). Например:

if (vs.size()) 
{ 
    std::wstring str = vs[0]; 
    MessageBox(0, str.c_str(), 0, 0); 
} 
+0

Теперь это дает мне имя одного файла, но только одно имя. он должен дать мне имя всех файлов, которые находятся в цикле. Ничего, он работает – Edgar

+0

Также как я хранил в строке? – Edgar

+0

Вы можете задать один вопрос по теме. –

1

Вот портативная версия с использованием нового ISO Standard Filesystem Library TS (техническая спецификация) для тех, кто с компиляторов, которые поддерживают его:

#include <vector> 
#include <iostream> 
#include <algorithm> 
#include <experimental/filesystem> 

// for readability 
namespace fs = std::experimental::filesystem; 

/** 
* Function object to test directory entries 
* for a specific file extension. 
*/ 
struct file_extension_is 
{ 
    std::string ext; 

    file_extension_is(std::string const& ext): ext(ext) {} 

    bool operator()(fs::directory_entry const& entry) const 
    { 
     return entry.path().extension() == ext; 
    } 
}; 

int main(int, char* argv[]) 
{ 
    try 
    { 
     // directory supplied on the command line if present 
     // else current directory 
     fs::path dir = argv[1] ? argv[1] : "."; 

     // place to store the results 
     std::vector<fs::directory_entry> entries; 

     // copy directory entries that have file extension ".txt" 
     // to the results 
     fs::directory_iterator di(dir); 
     fs::directory_iterator end; 

     std::copy_if(di, end, std::back_inserter(entries), 
      file_extension_is(".txt")); 

     // print it all out 

     std::cout << "Number of files: " << entries.size() << '\n'; 

     for(auto const& entry: entries) 
      std::cout << entry.path().string() << '\n'; 
    } 
    catch(std::exception const& e) 
    { 
     std::cerr << e.what() << '\n'; 
    } 
    catch(...) 
    { 
     std::cerr << "Unknown exception." << '\n'; 
    } 
}