将文件名从目录添加到char *数组。 C ++

时间:2017-08-16 11:57:04

标签: c++ arrays windows file

我试图从目录中获取文件名并将其放在char *数组中供以后使用。但这似乎不像我想要的那样工作。打印时只显示所有位置的最后一个文件名。

所以我的问题是如何在char * []中的每个位置添加文件名?

/*Placed outside*/
int i = 0;
char* Files[20] = {};
/*Placed outside*/

while (handle != INVALID_HANDLE_VALUE)
{
    char buffer[4100];
    sprintf_s(buffer, "%ls", search_data.cFileName);
    Files[i] = buffer;
    i++;
    if (FindNextFile(handle, &search_data) == FALSE)


  /*Printing I use ImGui*/
 #define IM_ARRAYSIZE(_ARR)  ((int)(sizeof(_ARR)/sizeof(*_ARR)))
static int listbox_item_current = 1;
ImGui::ListBox("", &listbox_item_current, Files, i, 4);

2 个答案:

答案 0 :(得分:0)

你可以使用C ++标准文件系统,但为此我猜你需要C ++ 17(或至少VS15),不太确定。

你必须包括:

#include <experimental/filesystem>
#include <filesystem>
using namespace std::experimental::filesystem::v1;

使用它应该很简单:

int i = 0;
const char * directoryToSearch = "C:\etc\etc";
for (const auto & file : directory_iterator(directoryToSearch)) {
    files[i] = new char[file.path().stem().string().length() + 1];
    strcpy(files[i], file.path().stem().string().c_str());
    ++i;
}

确实,您应该在使用它之后清理阵列。不要忘记,目前没有多少编译器支持这一点。

答案 1 :(得分:0)

打印时只显示所有位置的最后一个文件名。这是正常的:您将每次迭代的文件名存储在同一个缓冲区中,只需将缓冲区的地址复制到数组中即可。与问题无关,因为buffer是在循环(块作用域)内声明的自动变量,在循环外部使用它是未定义行为,因此您以悬空指针数组结束

正确的方法是使用2D数组char Files[MAX_PATH][20];并在每个插槽中存储文件名,或使用new分配的动态内存(或较低级别的malloc)。对于第二个选项,您可以手动执行 ,为每个文件名分配内存 - 并记住最后释放任何内容,或者您​​可以让标准库通过使用以下方式为您管理: / p>

std::vector<std::string> Files;
...
while(...) {
    ...
    File.push_back(search_data.cFileName);

亲爱的ImGui提供了一个ListBox ctor,允许传递不透明的数据存储和一个提取器,它可以在这里使用:

bool string_vector_items_getter(void* data, int idx, const char** out_text) {
    std::vector<std::string> *v = reinterpret_cast<std::vector<std::string> >(data);
    if (idx < 0 || idx >= v.size()) return false;
    *out_text = v[idx].c_str();
    return true;
}

然后:

ImGui::ListBox("", &listbox_item_current, &string_vector_items_getter, &Files, i, 4);

(注意:未经测试的代码!)