我使用Win32 API编写一个c程序FindNextFile来查找文件
#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:Access 违规写入位置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;
}
答案 0 :(得分:1)
您的代码中有很多错误。
首先,您没有正确使用FindNextFile,原型:
BOOL WINAPI FindNextFile(
_In_ HANDLE hFindFile,
_Out_ LPWIN32_FIND_DATA lpFindFileData
);
之后,您没有正确使用GetLastError()
,他们会触发异常。 GetLastError
返回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;
}
答案 1 :(得分: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);
}
答案 2 :(得分:0)
您的代码中存在一些问题。
您的原始代码为:
hNextFile = FindNextFile(fileName, &findFileData);
但是如果你查看prototype of FindNextFile()
,你会发现:
BOOL WINAPI FindNextFile( _In_ HANDLE hFindFile, _Out_ LPWIN32_FIND_DATA lpFindFileData );
因此,该函数返回BOOL
,第一个参数是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()
返回DWORD
,这是一个无符号的32位整数
但是在printf()
格式字符串中使用了%s
,它是原始C字符串的占位符。
相反,您可能希望使用%u
格式说明符(并使用_tprintf()
与TCHAR
模型保持一致):
_tprintf(_T("Last error code: %u\n"), GetLastError());
请注意,MSDN在Listing the Files in a Directory上有一个示例。