0

我使用 Win32 API FindNextFile编写 ac 程序来查找文件

#include<stdio.h>
#include<tchar.h>
#include<windows.h>

int _tmain(int argc, TCHAR *argv[])
{
    HANDLE hNextFile;
    WIN32_FIND_DATA findFileData;
    LPCTSTR fileName = argv[1]; //input argument "C:\test\file*.txt"

    hNextFile = FindFirstFile(fileName, &findFileData);

    while(hNextFile != INVALID_HANDLE_VALUE)
    {
        printf("long name: %s\t8dot3 name: %s\n", findFileData.cFileName, findFileData.cAlternateFileName);
        hNextFile = FindNextFile(fileName, &findFileData); //Unhandled exception here!
    }
    printf("%s", GetLastError());
    return 0;
}

当第一次调用 FindNextFile 时,它​​会抛出异常。异常信息:

findfile.exe 中 0x77178dc9 处的未处理异常:0xC0000005:访问冲突写入位置 0x005c0080。

你能给我一些建议吗?

提前致谢。


我已经像这样修改了我的代码,它工作正常。感谢皮埃尔的解释。

#include<stdio.h>
#include<tchar.h>
#include<windows.h>

int _tmain(int argc, TCHAR *argv[])
{
    HANDLE hNextFind;
    WIN32_FIND_DATA findFileData;
    LPCTSTR fileName = argv[1];
    BOOL result = TRUE;

    if((hNextFind = FindFirstFile(fileName, &findFileData)) == INVALID_HANDLE_VALUE)
        return 1;

    while(result)
    {
        _tprintf(TEXT("long name: %s\t8dot3 name: %s\n"), findFileData.cFileName, findFileData.cAlternateFileName);
        result = FindNextFile(hNextFind, &findFileData);
    }
    FindClose(hNextFind);
    return 0;
}
4

3 回答 3

1

您的代码中有很多错误。

  • 首先,您没有正确使用 FindNextFile,原型:

    BOOL WINAPI FindNextFile(
      _In_   HANDLE hFindFile,
      _Out_  LPWIN32_FIND_DATA lpFindFileData
    );
    
  • 之后,你没有GetLastError()正确使用,谁触发了异常。GetLastErrorreturn a DWORD,您可以将其打印为字符串。( http://msdn.microsoft.com/en-us/library/ms679360(v=vs.85).aspx )

这是您的代码应如下所示的示例:

#include<stdio.h>
#include<tchar.h>
#include<windows.h>

int _tmain(int argc, TCHAR *argv[])
{
    HANDLE hNextFile;
    WIN32_FIND_DATA findFileData;
    LPCTSTR fileName = argv[1]; //input argument "C:\test\file*.txt"

    hNextFile = FindFirstFile(fileName, &findFileData);
    BOOL res = TRUE;
  //^^^^^^^^^^^^^^^^

    while(hNextFile != INVALID_HANDLE_VALUE && res)
    //                                      ^^^^^^
    {
        printf("long name: %s\t8dot3 name: %s\n", findFileData.cFileName, findFileData.cAlternateFileName);
        res = FindNextFile(hNextFile, &findFileData); //Unhandled exception here!
      //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    }
    printf("%d", GetLastError());
    //      ^^  // You can also use FormatMessage as it is said in the documentation
    return 0;
}
于 2013-07-05T07:35:03.457 回答
0

您的代码中存在一些问题。

您的原始代码如下:

hNextFile = FindNextFile(fileName, &findFileData);

但是如果你检查 的原型FindNextFile(),你会发现:

BOOL WINAPI FindNextFile(
  _In_   HANDLE hFindFile,
  _Out_  LPWIN32_FIND_DATA lpFindFileData
);

因此,该函数返回 aBOOL并且第一个参数是 a HANDLE,这不是您在代码中所拥有的。

此外,您还有:

printf("long name: %s\t8dot3 name: %s\n", findFileData.cFileName,
       findFileData.cAlternateFileName);

但这与TCHAR您在代码的其他部分中使用的模型不一致。
为了保持连贯性,您应该使用_tprintf()代替,并使用或printf()装饰字符串:_T("...")TEXT("...")

// Use _tprintf() and _T("...") for coherence with TCHAR model
_tprintf(_T("long name: %s\t8dot3 name: %s\n"), 
         findFileData.cFileName, findFileData.cAlternateFileName);

此外,您还有:

printf("%s", GetLastError());

GetLastError()返回 a DWORD,它是一个无符号的 32 位整数。
但是在printf()您使用的格式字符串中%s,它是原始 C 字符串的占位符。
相反,您可能想要使用%u格式说明符(并_tprintf()用于与模型的一致性TCHAR):

_tprintf(_T("Last error code: %u\n"), GetLastError());

请注意,MSDN 有一个关于列出目录中的文件的示例。

于 2013-07-05T08:00:46.017 回答
0

FindNextFile返回 TRUE 或 FALSE,它不返回HANDLE. 您从中获得的原始句柄FindFirstFile仍然有效,直到您将其传递给FindClose.

hNextFile = FindFirstFile(fileName, &findFileData);
if(hNextFile != INVALID_HANDLE_VALUE)
{
    do
    {
        printf("long name: %s\t8dot3 name: %s\n", findFileData.cFileName, findFileData.cAlternateFileName);
    } while (FindNextFile(fileName, &findFileData));
    FindClose(hNextFile);
}
于 2013-07-05T07:26:05.890 回答