2014-10-01 37 views
0

在Linux上,我在使用ofstream類編寫UTF-16文件時遇到了一些麻煩,而相同的代碼在Windows上工作得非常好。下面是示例代碼爲什麼ofstream不會在二進制模式下在linux上編寫utf16?

MyString content; 
content = L"hello\r\n"; 
const short unsigned int* output = content.asUnicodeType<MyString::UTF16>().c_str(); 
ofstream outFile("test.txt", std::ios::out | std::ios::binary); 
outFile.write((char *)output, content.size() * sizeof(MyString::UTF16)); 
//outFile.write((char *)content.c_str(), content.size() * sizeof(wchar_t)); 
outFile.close(); 
return 0; 

我已經證實,輸出是否正確轉換爲UTF-16格式

(gdb) x /16b output 
0x61a288:  104  0  101  0  108  0  108  0 
0x61a290:  111  0  13  0  10  0  0  0 

然而,之後完成,我試圖打開文件。它看起來像內容被寫爲UTF8,儘管事實上我要求它以二進制模式寫入

如果我切換並將它寫爲寬字符,那麼在Linux上將內容正確寫爲UTF32。

任何建議都會很棒!

PS:由於平臺的限制,我不能使用C++ 11標準

感謝

+0

什麼是MyString? – Deduplicator 2014-10-01 20:41:05

+0

這只是一個包裝wchar_t字符串的類。當我寫輸出內容時,它並不重要。 – chickenmagician 2014-10-01 20:45:16

+0

'od -t x1 test.txt'給你什麼? – 2014-10-01 20:50:35

回答

1

這實際上寫的內容爲UTF-16,但因爲我錯過了BOM,沒在Windows文件打開我不認爲它,所以我認爲它寫的內容爲UTF8

1

如果content.asUnicodeType<MyString::UTF16>()返回std::string那麼你有未定義的行爲。 .c_str()返回由std::string擁有的c字符串,但在您的情況下,std::string是臨時對象,這會導致其c字符串被亞馬遜刪除。

爲了解決這個問題,你必須保持std::string只要四周,你需要的C-字符串:

auto output_s = content.asUnicodeType<MyString::UTF16>(); 
const short unsigned int* output = output_s.c_str(); 

我不知道這是否會解決你的問題,但是是個好主意無論如何修復未定義的行爲。

哦,順便說一句,嘗試在任何地方使用utf8,特別是在讀取和寫入文件時。無論你花費多少努力來正確使用utf16,你可能會做錯。 請參閱http://utf8everywhere.org

相關問題