本來想搞搞FindFirstFile 函數的,寫個代碼把指定目錄下的文件和屬性都打印出來,之後就是錯誤不斷。。。。
唉唉 先是FindFirsFile函數死命的報INVALID_HANDLE_VALUE錯誤,試了"e:"、"e:\\*.*"、"e:\\"等等都不行,後來乾脆把路徑改成“*”,突然發現不報INVALID_HANDLE_VALUE了,瞬間好開心啊~~ 沒想到接着問題又來。。。
typedef struct _WIN32_FIND_DATA { DWORD dwFileAttributes; FILETIME ftCreationTime; FILETIME ftLastAccessTime; FILETIME ftLastWriteTime; DWORD nFileSizeHigh; DWORD nFileSizeLow; DWORD dwReserved0; DWORD dwReserved1; TCHAR cFileName[MAX_PATH]; TCHAR cAlternateFileName[14]; } WIN32_FIND_DATA, *PWIN32_FIND_DATA, *LPWIN32_FIND_DATA;
這是微軟給的 WIN32_FIND_DATA結構,發現打印cFileName的時候,不管是printf還是puts還是std::cout都只能打印第一個字母。。坑爹啊!!!
先把代碼貼上,唉。。人懶,代碼修修改改的挺爛的,將就着看吧
WIN32_FIND_DATA fileData;
HANDLE fFind;
LPSYSTEMTIME sTime = new SYSTEMTIME;
fFind = FindFirstFile(path,&fileData);
if(fFind == INVALID_HANDLE_VALUE)
{
printf("can't find :%s\n",path);
std::cout << GetLastError() << "\n";
return false;
}
printf("max_path = %d\n",MAX_PATH);
do {
if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(strcmp((const char*)fileData.cFileName,".") && strcmp((const char *)fileData.cFileName,".."))
{
FileTimeToSystemTime(&fileData.ftCreationTime,sTime);
printf("is dir:%s,time :%d-%d-%d\n",fileData.cFileName,sTime->wYear,sTime->wMonth,sTime->wDay);
}
} else
{
FileTimeToSystemTime(&fileData.ftCreationTime,sTime);
std::string fname((char *)fileData.cFileName);
printf_s("%s ,time :%d-%d-%d\n",fileData.cFileName,sTime->wYear,sTime->wMonth,sTime->wDay);
}
//std::cout << fileData.cFileName << "\n";
//puts((char *)fileData.cFileName);
int i = 0;
#if 0
printf("name :");
while ((fileData.cFileName)[i] != '\0')
{
putchar((fileData.cFileName)[i]);
if (i > 20)
break;
i++;
}
printf(" i = %d" ,i);
putchar('\n');
#endif
}while (FindNextFile(fFind,&fileData));
return true;
谷歌了一堆之後,發現原來windows這麼坑爹。。一個char型 搞出TCHAR、WCHAR、wchar_t等一大堆類型。。不管了,這些我也沒搞清楚,反正大概就是指分爲兩種:一種是UNICODE,一種是ASCII(ps:貌似還是linux上簡單明瞭的- _-utf-8兼容acsII)。
然後如果用vs新建的工程的話。定義了_UNICODE的宏,然後代碼裏的LPCSTR和TCHAR啥的都是wchar_t咯,然後用“E:”這類char*的字符串就會出問題,然後用printf去打印wchar_t的話就會有問題了。。
嗯,最後說解決辦法吧,首先要去掉#include <tchar.h>。然後打開項目的屬性(右鍵)——“C/C++”——“預處理器”——“預處理器定義——編輯”看到 繼承的值 UNICODE和_UNICODE了吧,把下面“從父級或項目默認設置繼承”前面的勾勾去掉,最後保存重新編譯就ok拉~~~
水平有限,必有錯漏,如發現請必指出,互相交流,多多學習~ ^_^