2012-07-25 408 views
4

對我的軟件的要求是,包含導出數據的文件的編碼應爲UTF8。但是當我將數據寫入文件時,編碼始終是ANSI。 (我用記事本+ +進行檢查。)如何在C++中將文件編碼格式設置爲UTF8

目前我在做什麼是試圖文件通過閱讀它,將其轉換爲UTF8和寫作文本到一個新文件手動轉換。

linestd::string
inputFilestd::ifstream
pOutputFileFILE*

// ... 

if(inputFile.is_open()) 
{ 
    while(inputFile.good()) 
    { 
     getline(inputFile,line); 

     //1 
     DWORD dwCount = MultiByteToWideChar(CP_ACP, 0, line.c_str(), -1, NULL, 0); 
     wchar_t *pwcharText; 
     pwcharText = new wchar_t[ dwCount]; 

     //2 
     MultiByteToWideChar(CP_ACP, 0, line.c_str(), -1, pwcharText, dwCount); 

     //3 
     dwCount = WideCharToMultiByte(CP_UTF8, 0, pwcharText, -1, NULL, 0, NULL, NULL); 
     char *pText; 
     pText = new char[ dwCount ]; 

     //4 
     WideCharToMultiByte(CP_UTF8, 0, pwcharText, -1, pText, dwCount, NULL, NULL); 

     fprintf(pOutputFile,pText); 
     fprintf(pOutputFile,"\n"); 

     delete[] pwcharText; 
     delete[] pText; 
    } 
} 

// ... 

不幸的是,編碼仍然是ANSI。我搜索了一段時間的解決方案,但我總是遇到通過MultiByteToWideChar和WideCharToMultiByte的解決方案。但是,這似乎並不奏效。我在這裏錯過了什麼?

我也在這裏看到了一個解決方案,但大多數UTF8的問題處理C#和PHP的東西。

+2

如果你只寫英文字符的文件,記事本+ +是在顯示ANSI正確的,而且文件也將是UTF-8作爲其ANSI/ASCII編碼的所有英文字母UTF-8的有效子集。 – RedX 2012-07-25 09:15:06

+0

該文件將是一個包含英文字母,數字和一些特殊字符('/',';',':',',','。','(',')')的CSV文件。 – Exa 2012-07-25 09:19:55

+0

你的編譯器是否支持[std :: codecvt_utf8](http://en.cppreference.com/w/cpp/locale/codecvt_utf8)? – 2012-07-25 09:21:41

回答

1

在Windows在VC++ 2010,可以使用本地化方面的std :: codecvt_utf8_utf16(尚未在GCC實現,因爲據我所知)(即C++ 11)。 cppreference.com的示例代碼具有讀取/寫入UTF-8文件所需的所有基本信息。

std::wstring wFromFile = _T("teststring"); 
std::wofstream fileOut("textOut.txt"); 
fileOut.imbue(std::locale(fileOut.getloc(), new std::codecvt_utf8_utf16<wchar_t>)); 
fileOut<<wFromFile; 

它將ANSI編碼文件設置爲UTF-8(在記事本中檢查)。希望這是你所需要的。

0

AFAIK,fprintf()會進行字符轉換,因此不能保證將UTF-8編碼數據傳遞給它實際上會將UTF-8寫入文件。既然你已經自己轉換的數據,使用fwrite()代替你正在寫的UTF-8的數據原樣,如:

DWORD dwCount = MultiByteToWideChar(CP_ACP, 0, line.c_str(), line.length(), NULL, 0); 
if (dwCount == 0) continue; 

std::vector<WCHAR> utf16Text(dwCount); 
MultiByteToWideChar(CP_ACP, 0, line.c_str(), line.length(), &utf16Text[0], dwCount); 

dwCount = WideCharToMultiByte(CP_UTF8, 0, &utf16Text[0], utf16Text.size(), NULL, 0, NULL, NULL); 
if (dwCount == 0) continue; 

std::vector<CHAR> utf8Text(dwCount); 
WideCharToMultiByte(CP_UTF8, 0, &utf16Text[0], utf16Text.size(), &utf8Text[0], dwCount, NULL, NULL); 

fwrite(&utf8Text[0], sizeof(CHAR), dwCount, pOutputFile); 
fprintf(pOutputFile, "\n"); 
0

在Windows上,文件沒有編碼。每個應用程序都會根據自己的規則進行編碼。最好的辦法是在文件的前面放一個byte-order mark,並希望它能被識別。