std::vector 在 main() 中读取时内容发生变化

std::vector content change when read inside the main()

我正在编写这个函数来搜索计算机内的文件,但我遇到了一个问题:当我读取在搜索过程中找到的文件时(使用 main() 中的 for 循环),目录被破坏了. 通过一些调试,我看到当被推入 file_found 向量时,它们是完整的,但是当我读取主向量时,它们就像重叠并且在 end.How 处有一个“*”我可以吗解决这个问题?

    #include <stdio.h>
    #include <vector>
    #include <Windows.h>

    int SearchForFileW(WCHAR * fileName,LPWSTR dir,std::vector<LPWSTR>& file_found)
    {
        WIN32_FIND_DATAW winFindDataFirst;

        HANDLE hFile = FindFirstFileW(dir,&winFindDataFirst);

        if (!wcscmp(winFindDataFirst.cFileName,fileName))
        {
            wchar_t tmp[MAX_PATH] = { 0 };
            _snwprintf(tmp, wcslen(dir) - wcslen(L"*"), dir);
            wcscpy(dir, tmp);
            wcscat(dir, winFindDataFirst.cFileName);
            file_found.push_back(dir);
        }

        while (true)
        {
            if (FindNextFileW(hFile, &winFindDataFirst) == 0)
            {
                if (GetLastError() == ERROR_NO_MORE_FILES)
                {
                    return 0;
                }
                else
                { 
                    return -1;
                }
            }

            if (!wcscmp(winFindDataFirst.cFileName, L".") ||
                !wcscmp(winFindDataFirst.cFileName, L".."))
            {
                continue;
            }
            else if(!wcscmp(winFindDataFirst.cFileName,fileName))
            {
                wchar_t tmp[MAX_PATH] = { 0 };
                _snwprintf(tmp, wcslen(dir) - wcslen(L"*"), dir);
                wcscpy(dir, tmp);
                wcscat(dir, winFindDataFirst.cFileName);
                file_found.push_back(dir);
            }

            if ((winFindDataFirst.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
            {   
                wchar_t tmp[MAX_PATH] = { 0 };
                _snwprintf(tmp, wcslen(dir) - wcslen(L"*"), dir);
                wcscpy(dir, tmp);
                wcscat(dir, winFindDataFirst.cFileName);
                wcscat(dir, L"\*");
                SearchForFileW(fileName, dir,file_found);
                _snwprintf(tmp, wcslen(dir) - (wcslen(winFindDataFirst.cFileName) + wcslen(L"\*")), dir);
                wcscpy(dir, tmp);
                wcscat(dir, L"*");
            }
            else
            {
                printf("File:-------%S\n\n", winFindDataFirst.cFileName);
            }
        }

        return 0;
    }

int main()
{
    std::vector<LPWSTR> file;
    WCHAR dirBuff[MAX_PATH] = {0};

    wcscpy(dirBuff,L"c:\*");
    SearchForFileW(L"MyFile.txt", dirBuff,file);
    if (file.size() == 0)
    {
        printf("No file found");
    }
    else
    {
        for (int i = 0; i < file.size(); i++)
        {
            printf("File found at: %S\n", file.at(i));
        }
    }
}

LPWSTR 只是 someKindOfChar* 的糖衣,这意味着它是一个指针。这意味着 vector<LPWSTR> 是一个指针向量。每次,您都使用相同的缓冲区将文件名保存在 (dir) 中。所以你每次都把你的文件名复制到这里,然后把它的地址推送到你的向量中。

要修复,请使用 std::vector<std::wstring>

或者用困难的方法来做:对每个找到的文件使用 malloc(strlen(tmp)+1) 来为您的字符串分配数据。但是请注意,我相信 LPWSTR 代表 长指针宽字符串 。这意味着普通 strlen 可能不起作用,因为它可能包含特殊的非 ascii 字符

A std::vector<LPWSTR>std::vector<wchar_t*>(因为 LPWSTRwchar_t* 的类型定义)。

现在,拥有一个 原始拥有指针的向量 是非常脆弱的。你可以有一个原始 observing 指针的向量,并且当你使用这些指针引用它们时,你必须确保指向的字符串仍然被分配(有点 "live")。 那是不是你的情况。

最简单的做法是只使用 C++ 字符串 类,例如 std::wstring,而不是原始的 wchar_t* 指针。
因此,您可以将 vector<LPWSTR> 替换为 vector<wstring>。在这种情况下,字符串的生命周期将由 C++ 编译器和 STL 实现自动管理:您可以专注于算法的核心,而不是容易出错的字符串内存管理实施细节。