1. 程式人生 > >FindFirstFile 函式要注意多位元組字元問題

FindFirstFile 函式要注意多位元組字元問題

本來想搞搞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拉~~~

水平有限,必有錯漏,如發現請必指出,互相交流,多多學習~ ^_^

相關推薦

FindFirstFile 函式注意位元組字元問題

本來想搞搞FindFirstFile 函式的,寫個程式碼把指定目錄下的檔案和屬性都打印出來,之後就是錯誤不斷。。。。 唉唉 先是FindFirsFile函式死命的報INVALID_HANDLE_VALUE錯誤,試了"e:"、"e:\\*.*"、"e:\\"等等都不行,後來乾

位元組字元與寬字元

多位元組字符集——每個字元的編碼寬度不一,可為一個位元組或多個位元組。  (1)ASCII字元只佔一個位元組  (2)對於中文、日文等用兩個位元組  (3)一個字串中,如何區分哪個是中文字元,那個是ASCII字元呢?  “Windows程式設計”16進

ORA-29275部分位元組字元

紀錄一下關於:ORA-29275部分多位元組字元的問題。 在做ogg的時候,因為字元佔位元組數的原因,我把編碼從:AL32UTF8改成了ZHS16GBK 具體操作見:https://www.cnblogs.com/jay-xu33/p/5210098.html 修改完編碼之後,開啟

新手學習VUE踩坑之旅---methods裡面使用箭頭函式注意this

VUE的methods物件裡面如果函式使用箭頭函式會導致this指向的不是vue例項$vm 例子:想寫一個點選事件:點選輸入框的“x”,即可清空文字框的內容 首先為輸入框增加一個ref屬性(ref=“inputUser”),然後為“x”加一個點選事件(@click=“deleteInp”)

ORA-29275:部分位元組字元

select addr from test_app 如果addr中有半個中文字元則會報這個異常,原因為Oracle編碼問題。 解決方法一: select to_nchar(addr)  from test_app 解決方法二: 檢查他們Oracle的nls_lang環境變

vs2013使用位元組字元,編譯出錯

提示如上圖 解決方法: 下載該網址對應的exe進行安裝 官網地址 https://www.microsoft.com/zh-cn/download/details.aspx?id=40770 掃

unicode字元位元組字元的相互轉換介面

作者:朱金燦           發現開原始碼的可利用資源真多,從sqlite3的原始碼中摳出了幾個字元轉換介面,稍微改造下了發現還挺好用的。下面是實現程式碼:/* ** Convert a UTF-8 string to microsoft unicode (UTF-16?

位元組字元轉換成寬字串

//MultiByteToWideChar用於將多位元組字串轉換成寬字串;函式WideCharToMultiByte將寬字串轉換成等價的多位元組字串。//This function maps a character string to a wide-character (U

C++輸出中文字元 C/C++位元組字元與寬字元的輸出

使用C++標準庫的iostream,可以方便地將控制檯、檔案、字串以及其它可擴充的外部表示作為流來處理,但要處理中文,卻會碰到很多問題。本人原來沒怎麼用過這個iostream,這幾天嘗試用這個寫點東西,一會兒不能輸出中文,一會兒不支援中文檔名的,搞得頭大。網上搜了搜,沒有發現適用於所有情況的解決方案。不過後來

ORA-29275部分位元組字元的奇怪問題

寫儲存過程時遇到了這個奇怪的問題,上網查了半天都說編碼不一致什麼的,弄了半天也不行,把包頭和包體單獨分開執行能通過,就是edit包的時候編譯不過,一直報這個29275的錯,一段一段的刪程式碼發現了問題,有兩處elsif

Opencv中reshape函式注意的細節

#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; void PrintMat( Mat &_m)

C語言中使用extern修飾函式注意(轉)

用extern修飾函式是表示被修飾的函式定義在當前檔案外,而該函式用extern宣告型別後就可以被當前檔案呼叫了。使用extern修飾某函式時,對該函式的呼叫是在連線階段才被處理的。下面我們看一段程式碼。 /*********************************************** *

linux 寬字元位元組字元之間的轉換

最近再調linux下證書驗證問題,由於要對客戶端傳送過來的證書在伺服器上與根證書進行認證,所以在讀取證書、驗證證書時設計到了編碼轉換問題。在windows下,使用MultiByteToWideChar和WideCharToMultiByte沒有問題,但在linux下,不存在這

[系列] Go 使用 defer 函式 注意的幾個點

概述 defer 函式大家肯定都用過,它在宣告時不會立刻去執行,而是在函式 return 後去執行的。 它的主要應用場景有異常處理、記錄日誌、清理資料、釋放資源 等等。 這篇文章不是分享 defer 的應用場景,而是分享使用 defer 需要注意的點。 咱們先從一道題開始,一起來感受下 ... func ca

在linux c++類中的成員函式裡建立執行緒注意的地方

如何在linux 下c++中類的成員函式中建立多執行緒 linux系統中執行緒程式庫是POSIX pthread。POSIX pthread它是一個c的庫,用C語言進行多執行緒程式設計我這裡就不多說了,網上的例子很多。但是如何在C++的類中實現多執行緒程式設計呢?如果套

Struts2整合spring注意action的配置,設定例模式

struts 2的Action是多例項的並非單例,也就是每次請求產生一個Action的物件。原因是:struts 2的Action中包含資料,例如你在頁面填寫的資料就會包含在Action的成員變數裡面。如果Action是單例項的話,這些資料在多執行緒的環境下就會相互影響,例如造成別人填寫的資料被你看

執行緒Runnable匿名內部類一定注意大坑

通常情況下,當需要模擬多執行緒的時候我們會選擇兩種方式。第一種就是自己實現Runnable類,然後在主類中呼叫我們自己實現的Runnable,例如: package concurrent; public class MyRunnable implements Runnab

將類模板中的成員函式在類模板外定義注意的地方

1、在宣告類前要有類模板的宣告 2、每個成員函式在模板外定義的時候前面都要有類模板的宣告,注意是每個。 #include<iostream> using namespace std; template<class numtype> //類模板宣

MySql中表聯查是注意的事項

1.簡單介紹一下多表聯查的概念 當要查詢的資料在多張表時,使用多表聯查 2.多表聯查的分類 MySQL聯合查詢 交叉聯合查詢 cross join 內連線聯合查詢 inner join (MySQL簡寫join) 外連線聯合查詢: 左外連線聯合查詢 left oute

字元(unicode)和位元組的轉換(std::string與std::wstring轉換)

#include <string> #include <windows.h> using namespace std; //Converting a WChar string to a Ansi string std::string W