【问题标题】:List all text files in directory in C++列出 C++ 目录中的所有文本文件
【发布时间】:2016-02-16 05:31:37
【问题描述】:

我正在尝试将目录中所有 txt 文件的名称存储在一个字符串中并打印出来。我需要计算目录中txt文件的数量,然后打印名称。计数的部分正在工作,但我似乎无法让这个名字起作用。我找到了一些示例,但它们在我正在使用的 Visual Studio 中不起作用。

这是我的代码。

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;
}

【问题讨论】:

  • 哎呀。你能在你的代码上先Ctrl+K然后Ctrl+D,然后再发布吗?
  • 您所说的 “我似乎无法使用这个名称” 到底是什么意思? WIN32_FIND_DATAcFileName。是空的吗?顺便说一句,您应该检查 FILE_ATTRIBUTE_DIRECTORY 的文件属性
  • 不应该是"..//Menu//Circuitos//*.txt"吗?
  • 柜台工作完美。它正在计算 txt 文件的数量,因此路径必须有效。
  • cFileName返回的东西我不知道怎么转成字符串,只返回一个值,但是目录里有多个文本文件。

标签: c++ windows file


【解决方案1】:

FindFirstFile 已经拥有第一个有效句柄。如果您立即致电FindNextFile,则第一个句柄将丢失。您的示例中的文件计数将是错误的。

使用do-while 循环代替。

另外,从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::vectorstd::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-strings。在许多情况下,您必须使用.c_str() 来获取字符数组。例如:

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

【讨论】:

  • 现在它确实给了我一个文件的名称,但只有一个名称。它应该给我在循环中找到的所有文件的名称。没关系,它有效
  • 我也是如何存储在字符串中的?
  • 每个主题可以问一个问题。
  • 主要问题中说明了“我正在尝试将目录中所有txt文件的名称存储在一个字符串中并打印出来”但是谢谢
【解决方案2】:

这是一个使用新的ISO 标准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';
    }
}

【讨论】:

    猜你喜欢
    • 2017-02-16
    • 2011-06-13
    • 2017-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 2015-06-13
    相关资源
    最近更新 更多