C ++中目录列表文件出错

时间:2011-03-01 07:30:48

标签: c++ directory

我的代码出现问题。每当我运行程序时,最后一次文件搜索将返回零值,其中不应该。

这是代码:

#include <vector>
#include <string>
#include <windows.h>
#include <stdio.h>
#include <iostream> 
#include <conio.h>

using namespace std;

string GetPath(string path){
        char directory[1024];
        vector <string> filelist;
        strcpy_s(directory,path.c_str());
        BOOL checker;

            WIN32_FIND_DATA findFileData;
            HANDLE hFind = FindFirstFile((LPCSTR)directory, &findFileData);
            cout <<"Files in:" <<"\n"<<directory<<"\n"<<endl;
            checker = FindNextFile(hFind, &findFileData);

            while(checker)
            {
                checker = FindNextFile(hFind, &findFileData);
                filelist.push_back(findFileData.cFileName);//save file list in vector
                cout << findFileData.cFileName << endl;
            }

            DWORD error = GetLastError();
            if( error != ERROR_NO_MORE_FILES)
            {

            }
            /*for (unsigned i=1;i<filelist.size();i++){
                cout << filelist[i]<<endl;//print out the vector
            }*/


            return 0;
}

int main()
{
   string path;
   path="C:\\Program Files\\*.*";
   vector <string> handler;
   path = GetPath(path);
}

5 个答案:

答案 0 :(得分:1)

首先,您需要检查从FindFirstFile()返回的hFind,因为它可能会返回INVALID_HANDLE_VALUE

其次,你的while循环应该是这样的

while(FindNextFile(hFind, &findFileData)!= 0)
{
    filelist.push_back(findFileData.cFileName);//save file list in vector
}

DWORD error = GetLastError();
if( error != ERROR_NO_MORE_FILES)
{
    // You are not expecting this error so you might want to do something here.
}

答案 1 :(得分:1)

在我看来,你不应该在循环中调用FindNextFile:我想如果你仔细看看输出,你会注意到列表中缺少每个SECOND文件。

这是因为在while条件下调用FindNextFile会将下一个文件详细信息加载到FindFileData中。然后下一行代码(在while循环内)再次执行此过程,用第二行覆盖第一个匹配。因此,您只能获得每一秒。

对于偶数个文件,您也会遇到最后描述的困难。

答案 2 :(得分:1)

我注意到的一件事是你的GetPath函数返回一个字符串。最后你做:返回0;这将调用以char *作为参数的字符串构造函数,并尝试使用空指针构造字符串。我认为这会导致大多数STl实现中的崩溃: - )。

来你的问题,你可以试试这个:

#include <Strsafe.h>

//from MSDN
void 
DisplayError(LPTSTR lpszFunction) 
{ 
    // Retrieve the system error message for the last-error code
    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError(); 

    FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | 
                   FORMAT_MESSAGE_FROM_SYSTEM |
                   FORMAT_MESSAGE_IGNORE_INSERTS,
                   NULL,
                   dw,
                   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                   (LPTSTR) &lpMsgBuf,
                   0, 
                   NULL );

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); 

    StringCchPrintf((LPTSTR)lpDisplayBuf, 
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 

    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
}

void 
GetPath(string path)
{
    vector <string> filelist;

    WIN32_FIND_DATA findFileData;
    HANDLE hFind = FindFirstFile(path.c_str(), &findFileData);

    if (hFind == INVALID_HANDLE_VALUE) 
    {
        DisplayError("FindFirstFile");
        return;
    } 

    cout <<"Enumerating files in: " <<"\n"<< path << "\n" << endl;

    while( FindNextFile(hFind, &findFileData) != 0 )
    {
        filelist.push_back( findFileData.cFileName );//save file list in vector
    }

    if (  ERROR_NO_MORE_FILES != GetLastError() )
    {
        DisplayError("FindFirstFile");
    }

    FindClose(hFind);

    unsigned int listSize = filelist.size();

    cout << "List Count: " << listSize << "\n";

    for (unsigned i=0; i  < listSize; ++i)
    {
        cout << filelist[i] << "\n";//print out the vector
    }

    cout << "\nListing complete\n" << endl;
}

int main()
{
    string path;
    path="C:\\Program Files\\*.*";
    GetPath(path);
}

告诉我们在while循环完成后你收到了什么错误代码。

答案 3 :(得分:1)

尝试将其作为完整性检查:

#include <tchar.h>
#include <stdexcept>
#include <vector>
#include <string>
#include <iostream>
#include <windows.h>

#ifdef UNICODE
typedef std::wstring tstring;
static std::wostream& tcout = std::wcout;
#else
typedef std::string tstring;
static std::ostream& tcout = std::cout;
#endif

std::vector<tstring> GetPath(tstring const& path)
{
    WIN32_FIND_DATA findFileData;
    HANDLE const hFind = FindFirstFile(path.c_str(), &findFileData);
    if (hFind == INVALID_HANDLE_VALUE)
        throw std::runtime_error(""); // realistically, throw something useful

    std::vector<tstring> filelist;
    do filelist.push_back(findFileData.cFileName);
    while (FindNextFile(hFind, &findFileData));
    FindClose(hFind);
    if (GetLastError() != ERROR_NO_MORE_FILES)
        throw std::runtime_error(""); // realistically, throw something useful
    return filelist;
}

int _tmain()
{
    std::vector<tstring> files = GetPath(_T("C:\\Program Files\\*.*"));
    for (std::vector<tstring>::const_iterator iter = files.begin(), iter_end = files.end(); iter != iter_end; ++iter)
        tcout << *iter << _T('\n');
}

如果有效,请清理错误处理逻辑并使用它; - ]。如果没有,那么@young是正确的,你有本地化问题;更改项目设置以使用Unicode作为字符集,它应该可以工作。

答案 4 :(得分:0)

这是我的回答

#include <vector>
#include <string>
#include <windows.h>
#include <stdio.h>
#include <iostream> 
#include <conio.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <time.h>
#include <exception>
#include <WinBase.h>
#include <tchar.h>
#include <strsafe.h>
#include <algorithm>

        using namespace std;
int ifException(string directory) throw()
    {
        DWORD returnvalue;
        returnvalue = GetFileAttributes(directory.c_str());
            if(returnvalue == ((DWORD)-1))
            {
                return 0;
            }
            else
            {   
                return 1;
            }
}
string FileTime(string filename, string path){

    char timeStr[ 100 ] = "";
    char fpath[9999];
    string buffer;

                replace (path.begin(),path.end(),'*','\0');
                replace (path.begin(),path.end(),'.','\0');
                strcpy_s(fpath,path.c_str());
                path = filename;
            struct stat buf;
            string filepath;
            filepath = fpath;
            filepath += filename;
            //cout << filepath << endl;
            strcpy_s(fpath,filepath.c_str());
            if (!stat(fpath, &buf))
            {
                strftime(timeStr, 100, "%d-%m-%Y %H:%M:%S", localtime(&buf.st_mtime));
            }
            buffer = filename;
            buffer += "\t\t";
            buffer +=timeStr;
            return buffer;
}


vector <string> GetPath(string path)
    {
            char directory[9999];
            vector <string> filelist;
            string buffer;
            strcpy_s(directory,path.c_str());
            BOOL checker;
                WIN32_FIND_DATA findFileData;
                HANDLE hFind = FindFirstFile((LPCSTR)directory, &findFileData);


                try
                    {
                        ifException(directory);

                    }catch(int i)
                    {   
                        if (i==0)
                        {
                            _getch();
                            exit(1);
                        }
                    }
                buffer = findFileData.cFileName;
                filelist.push_back(buffer);
                checker = FindNextFile(hFind, &findFileData);
                while(checker)
                {
                    checker = FindNextFile(hFind, &findFileData);
                        buffer = findFileData.cFileName;
                        buffer = FileTime(buffer,path);
                    filelist.push_back(buffer);//save file list in vector
                    if(checker == 0)
                    {
                        filelist.resize(filelist.size());
                        return filelist;
                    }
                }
    return filelist;
    }

    int main()
    {
       string path;

       path="C:\\Documents and Settings\\OJT\\My Documents\\*.*";// the directory
       vector <string> handler;
       handler = GetPath(path);
        for (unsigned i=1;i<handler.size()-1;i++)
        {
            cout << handler[i]<<endl;//print out the vector
        }
       _getch();
    }