2010-06-10 67 views
47

我只想在C++中編寫幾行簡單的文本文件,但我希望它們以UTF-8編碼。什麼是最容易和最簡單的方法呢?如何將std :: string寫入UTF-8文本文件

+11

std庫不能處理utf-8是瘋狂的。這就是爲什麼我們不得不在寬字符串和字節字符串之間進行大量的轉換,並且使用了一些尷尬的語言環境爲什麼這些年來還沒有像std :: utf8string這樣的東西? –

+4

,因爲C/C++必須與非現有硬件兼容? :P – GameDeveloper

回答

9

libiconv是我們所有編碼和解碼需求的絕佳庫。

如果您使用的是Windows,則可以使用WideCharToMultiByte並指定您需要UTF8。

7

如果用「簡單」表示ASCII,則不需要進行任何編碼,因爲UTF-8中ASCII值爲127或更小的字符是相同的。

+1

我猜他還有一些其他角色,但他需要編碼,他在他的字符串中存儲。但也許不是:) –

50

UTF-8影響std::string的唯一方法是size(),length(),並且所有索引均以字節爲單位,而不是字符。

而且,正如sbi指出的那樣,遞增由std::string提供的迭代器將按字節向前邁進,而不是按字符向前邁進,因此它實際上可以指向多字節UTF-8代碼點的中間。標準庫中沒有提供支持UTF-8的迭代器,但在'Net'上有一些可用的迭代器。如果你還記得的話,你可以把UTF-8放入std::string,寫入一個文件等等,全部以通常的方式(我的意思是你在沒有UTF-8的情況下使用std::string的方式) 。

你可能想用一個字節順序標記來啓動你的文件,這樣其他程序就會知道它是UTF-8。

+2

爲了完整性,將迭代器添加到第一句中,它們與索引相同。 – sbi

+14

許多程序在讀取UTF-8時會憋住BOM,並且會導致一些程序認爲文本是UTF-16。 –

+1

@TimSeguine:這只是說很多程序對UTF-8沒有或很差的支持。 –

20

有很好的小庫從C++使用UTF8工作:utfcpp

+2

這是最酷的圖書館。鑑於你知道什麼是UTF8,你不需要其他任何東西。 – GameDeveloper

5
std::wstring text = L"Привет"; 
QString qstr = QString::fromStdWString(text); 
QByteArray byteArray(qstr.toUtf8());  
std::string str_std(byteArray.constData(), byteArray.length()); 
+10

注意:此代碼需要[Qt toolkit](https://qt-project.org/)。 – michaelb958

-28

至於UTF-8是multibite字符的字符串,所以你得到一些問題要解決,這是一個壞主意/取而代之的正常使用Unicode格式。

所以我認爲最好的是使用普通的ASCII字符文本與一些codding集。如果您單獨使用超過2套不同符號 (語言),則需要使用Unicode。

這是相當罕見的情況。在大多數情況下,足夠2套符號。對於這種常見情況,使用ASCII字符,而不是Unicode。

使用UTF-8等多字符字符的效果只能得到中國的傳統,阿拉伯文或一些象形文字。這是非常非常罕見的情況!

我不認爲有很多人需要這個。所以不要使用UTF-8!這避免了操縱這些琴絃的強烈頭痛。

+4

「正常的Unicode」是什麼意思?我將假設你的意思是大多數Java和Windows程序員認爲Unicode的意思是:UTF16。這也不是一個恆定的寬度編碼(不是每個字符都需要2個字節)。大約一半的互聯網用戶來自中國。很稀少! –

+2

@Anatoly - 一些背景閱讀:http://www.joelonsoftware.com/articles/Unicode.html,http://www.theregister.co.uk/2013/10/04/verity_stob_unicode/,http:// www .utf8everywhere.org /。 如果你只讀一個,請閱讀其中的第一個。 你可能會改變你的建議,不要使用UTF-8! –

+2

使用utf-8的原因是它可以對所有的Unicode代碼點進行編碼,並且對於拉丁語言來說它是高效的內存。缺點的確是你有可變長度編碼。請注意,utf-16與ucs-2之間有所不同。 ucs-2是你提到的:每個字符固定2個字節,但缺點是它不能編碼所有的編碼點。 – gast128

8

什麼是最容易和最簡單的方法呢?

C++中的UTF8最直觀和最簡單的由此處理是用於使用簡易替換爲std::string肯定。由於互聯網仍然缺乏一個,我去實現我自己的功能:

tinyutf8(編輯:現在Github)。

該庫提供了一個非常輕量級的投遞preplacement爲std::string(或std::u32string如果你願意,因爲你遍歷碼點寧可字符 S)。 Ity在快速訪問和小內存消耗之間成功實施,同時非常強大。這種對'無效'UTF8序列的穩健性使得它(幾乎完全)與ANSI(0-255)兼容。

希望這會有所幫助!

+0

您的圖書館看起來相當不錯,但其許可證非常有限。 –

+0

它以什麼方式限制?你要我發佈它的許可證是什麼? –

+1

GPL的意思是,如果我把你的頭文件包含在我的程序中,我還必須製作我的程序GPL。相當有限,你不覺得嗎?我會建議像這樣的小型圖書館BSD風格的許可證。 –

0

使用Glib::ustringglibmm

它是唯一廣泛使用的UTF-8字符串容器(AFAIK)。雖然基於字形(不是字節),它具有與std::string相同的方法簽名,因此端口應該是簡單的搜索和替換(只需確保在將數據加載到ustring之前,您的數據是有效的UTF-8)。

相關問題