從C++遍曆路徑中含有漢字的檔案夾看寬窄字串轉換的問題

來源:互聯網
上載者:User

整理者:finallyliuyu

    NLP研究者或者開發人員如果選用C++語言作為開發工具。那麼首先需要克服兩個難題。

    第一個難題是:學會在C++中使用Regex。鑒於C++本身並不支援Regex,所以我們需要藉助第三方庫boost.中的regex子庫。網路上有很多關於boost的安裝方法,比如有的方法介紹如何部分安裝boost庫,我這裡也整理了一個如何完整安裝boost庫的方法:《C++安裝boost》這個我實驗過,上面的方法是可行的。但是安裝boost庫之前,需要安裝python26。

    第二個難題是:寬窄字串轉換問題,這個問題目前我只是整理了部分解決方案。日後有新的總結會增加進來。此篇博文給出針對第二個難題的一些知識整理。以下博文將分為兩個部分:第一個部分講解:利用boost正則庫進行字串處理的時候需要進行的字串轉換;第二個部分講解:遍曆路徑中含有漢字的檔案夾時的路徑字串轉換問題。

第一部分:利用boost正則庫進行字串處理的時候需要進行的字串轉換

如果字串中含有漢字,應該使用的Regex類型為boost::wregex;

還要將字串從string轉換為wstring

string->wstring:的大概思路是將string用c_str()轉換成c格式的字串,然後將char 型的字串轉化成 wchar_t型的字串,然後wchart_t的字串轉化成wstring

string->wstring代碼如下:

************************************************************************//*  功能:將窄字元轉化成寬字元,string->wstring                         *//************************************************************************/wstring myMultibyteToWideChar(string sResult){int iWLen=MultiByteToWideChar( CP_ACP, 0, sResult.c_str(), sResult.size(), 0, 0 );// 計算轉換後寬字元串的長度。(不包含字串結束符)wchar_t *lpwsz= new wchar_t [iWLen+1];MultiByteToWideChar( CP_ACP, 0, sResult.c_str(), sResult.size(), lpwsz, iWLen ); // 正式轉換。lpwsz[iWLen] = L'\0'; wstring wsResult(lpwsz);delete []lpwsz;return wsResult;}

函數中調用了windows.h中的函數MultiByteToWideChar函數將char型字串轉化成wchar_t型的字串。

為了讓經過正則處理後的字串在控制台正常顯示,還有將wstring->string

代碼如下(代碼中也用到了windows.h中的函數):

/************************************************************************//* 將寬字元串轉化成窄字串用於輸出                                     *//************************************************************************/string myWideCharToMultibyte(wstring wsResult){string sResult;int iLen= WideCharToMultiByte( CP_ACP, NULL, wsResult.c_str(), -1, NULL, 0, NULL, FALSE ); // 計算轉換後字串的長度。(包含字串結束符)char *lpsz= new char[iLen];WideCharToMultiByte( CP_OEMCP, NULL, wsResult.c_str(), -1, lpsz, iLen, NULL, FALSE); // 正式轉換。sResult.assign( lpsz, iLen-1 ); // 對string對象進行賦值。delete []lpsz;return sResult;}

第二部分:

遍曆路徑中含有漢字的檔案夾時的路徑字串轉換問題。

首先給出測試代碼:

int _tmain(int argc, _TCHAR* argv[]){ int end;FindFile("E:\\舊電腦");   cout<<"finish"<<endl;cin>>end;}
 
 
 
 
 
 
 
 
 
 
 
檔案夾情況如下:
 
 
其中破舊電腦的子檔案夾下面還有檔案:
 

此部分給出兩種方法。

方法一(修改來自同學劉洋的代碼)

用此方法要先將VS2008項目屬性設定為Multibyte。顯示的字串將會出現亂碼

void FindFile(char * filePath){  WIN32_FIND_DATA  FileData;   //這兩個是系統參數,hFile是控制代碼 ,FileData是一些標誌HANDLE   hFile; char dir[1000];memset(dir,0,1000);sprintf_s(dir,1000,"%s%s",filePath,"\\*.*");hFile=FindFirstFile(dir,&FileData);if (hFile == INVALID_HANDLE_VALUE) //FindFirstFile()如果沒找到進行這一步{printf ("%s\n", "沒有找到檔案");return ;} bool bFinish=false;while(!bFinish){   char *temp= FileData.cFileName;//這個就是FindFirstFile()返回的檔案的名字if((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)&&strcmp(temp,".")&&strcmp(temp,"..") )//判斷返回的東西是不是目錄或者"." "..",因為一個目錄下都有"." ,".."兩個檔案夾{char  dirassist[3000];memset(dirassist,0,3000);sprintf_s(dirassist,3000,"%s%s%s",filePath,"\\",temp);FindFile(dirassist);}//elseif(((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0))//判斷是不是ClassList.txt這個檔案{cout<<FileData.cFileName<<endl;}bFinish = (FindNextFile(hFile, &FileData) == false);//看目錄下還有沒有檔案,有的話bFinish=flase 繼續迴圈}
 
結果如下:

 
方法二(來自網友茅柳野)
此版本無需改變工程字元集,預設為unicode即可
/************************************************************************//* 遍曆檔案夾                                                                     *//************************************************************************/ void FindFile(wchar_t *pFilePath) { WIN32_FIND_DATA FindFileData; HANDLE hFind = INVALID_HANDLE_VALUE; wchar_t  DirSpec[MAX_PATH + 1];// 指定路徑  DWORD dwError; wcsncpy (DirSpec, pFilePath, wcslen(pFilePath) + 1); wcsncat (DirSpec, L"\\\*", 3); hFind = FindFirstFile(DirSpec, &FindFileData); if (hFind == INVALID_HANDLE_VALUE) { wprintf(L"Invalid file handle. Error is %u ", GetLastError()); return ; }  else if (FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY ) { wchar_t temp[3000]; memset(temp,0,3000*sizeof(wchar_t));    wprintf_s(temp,L"%s\\%s\n",pFilePath,FindFileData.cFileName);int iLen= WideCharToMultiByte( CP_ACP, NULL, temp, -1, NULL, 0, NULL, FALSE ); // 計算轉換後字串的長度。(包含字串結束符)char *lpsz= new char[iLen];WideCharToMultiByte( CP_OEMCP, NULL, temp, -1, lpsz, iLen, NULL, FALSE); // 正式轉換。cout<<lpsz<<endl;delete []lpsz;     }  else if(FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY && wcscmp(FindFileData.cFileName, L".") != 0 && wcscmp(FindFileData.cFileName, L"..") != 0) {   //找到目錄 wchar_t Dir[MAX_PATH + 1]; wcscpy(Dir, pFilePath); wcsncat(Dir, L"\\", 2); wcscat(Dir, FindFileData.cFileName); FindFile(Dir); }while (FindNextFile(hFind, &FindFileData) != 0) { if (FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY)  {   //找到檔案 //fwprintf(fp, L"%s\\", pFilePath); //fwprintf(fp, L"%s\n", FindFileData.cFileName); wchar_t temp[3000]; memset(temp,0,3000*sizeof(wchar_t)); wcscpy(temp,pFilePath); wcscat(temp,FindFileData.cFileName); int iLen= WideCharToMultiByte( CP_ACP, NULL, temp, -1, NULL, 0, NULL, FALSE ); // 計算轉換後字串的長度。(包含字串結束符) char *lpsz= new char[iLen]; WideCharToMultiByte( CP_OEMCP, NULL, temp, -1, lpsz, iLen, NULL, FALSE); // 正式轉換。 cout<<lpsz<<endl; delete []lpsz;  }  else if(FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY && wcscmp(FindFileData.cFileName, L".") != 0 && wcscmp(FindFileData.cFileName, L"..") != 0)  { //找到目錄 wchar_t Dir[MAX_PATH + 1]; wcscpy(Dir, pFilePath); wcsncat(Dir, L"\\", 2); wcscat(Dir, FindFileData.cFileName); FindFile(Dir); } } dwError = GetLastError(); FindClose(hFind); if (dwError != ERROR_NO_MORE_FILES) { wprintf (L"FindNextFile error. Error is %u ", dwError); return; } }
 
運行結果如下:

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.