設置 | 登錄 | 註冊

目前共有5篇帖子。

【代碼】將wchar_t字符數組直接寫入txt文件的方法

1樓 巨大八爪鱼 2016-1-24 11:56
【說明】
在Windows作業系統下,wchar_t的大小是兩個字節,其默認的編碼方式是UTF-16(Unicode的一種存儲方式)。其中,每個基本多語言平面字符占據兩個字節,也就是一個wchar_t數組元素;每個輔助平面字符占據四個字節,即兩個wchar_t數組元素。例如,字符「長」是基本多語言平面字符,而「卒瓦」這兩個字合在一起的那個漢字就是一個輔助平面字符(這個字符目前在Arslanbar還無法發表)。注意,如果用wcslen函數測定wchar_t字符數組的長度,數組中的每個輔助字符將會被認為是兩個字符。
為了能讓文本編輯器識別寫入的txt文件是UTF-16編碼格式,必須在文件開頭寫入兩個字節的BOM作為標記(對於UTF8則是三個字節的BOM,不過這個BOM是可寫可不寫的)。UTF-16分為大尾序和小尾序兩種格式,其BOM分別是0xFEFF和0xFFFE。在Windows和Linux系統上一般使用小尾序,而在Mac系統上則一般使用大尾序。在C++中我們可以用一個char字符數組存儲這個BOM,然後寫入txt文件的開頭。
【代碼】
wchar_t wstr[] = L"Windows作業系統內核中的字符表示為UTF-16小尾序,可以正確處理、顯示以4位元組存儲的字符。但是Windows API實際上僅能正確處理UCS-2字符,即僅以2位元組存儲的,碼位小於U+FFFF的Unicode字符。其根源是Microsoft C++語言把wchar_t數據類型定義為16比特的unsigned short,這就與一個wchar_t型變量對應一個寬字符,可以存儲一個Unicode字符的規定相矛盾。相反,Linux平台的GCC編譯器規定一個wchar_t是4位元組長度,可以存儲一個UTF-32字符,寧可浪費了很大的存儲空間。下例運行於Windows平台的C++程序可說明此點。";
char bom[] = {0xff, 0xfe}; // UTF-16小尾序的BOM
wchar_t *pStr;
FILE *fp;
fopen_s(&fp, "utf16.txt", "wb"); // 打開文件
fwrite(bom, sizeof(bom), 1, fp); // 在文件頭部寫入BOM
for (pStr = wstr; *pStr != '\0'; pStr++)
    fwrite(pStr, sizeof(wchar_t), 1, fp); // 寫入字符串,不寫入末尾的\0
fclose(fp); // 關閉文件
【運行結果】

2樓 巨大八爪鱼 2016-1-24 12:00
如果想要以UTF-8編碼格式將wchar_t字符數組寫入txt文件,就必須進行編碼轉換。一般使用WideCharToMultiByte函數進行轉換。具體請參閱:
https://zh.arslanbar.net/post.php?t=23651
註:UTF-8是Unicode的另一種存儲方式。
3樓 巨大八爪鱼 2016-1-24 12:46
【代碼】
讀取UTF-16編碼格式的txt文件的C++代碼:
wchar_t wstr[300];
wchar_t *pStr = wstr;
FILE *fp;
fopen_s(&fp, "utf16.txt", "rb");
fseek(fp, 2, SEEK_SET); // 跳過文件開頭兩個字節的BOM
while (fread(pStr, sizeof(wchar_t), 1, fp), !feof(fp))
    pStr++; // 讀取文件,直到文件結束
*pStr = '\0'; // 在wstr字符串末尾添加\0
::MessageBoxW(m_hWnd, wstr, L"文件內容", MB_ICONINFORMATION);
fclose(fp);
運行結果:

4樓 巨大八爪鱼 2016-1-24 13:03
對於UTF-8文本文件,可以使用BOM也可以不使用BOM(三個字節),但Unicode標準既不推薦也不強制在UTF-8文本文件中使用BOM。
對於UTF-16文本文件,文件開頭必須寫入兩個字節的BOM,並且要指定是使用小尾序還是大尾序。
5樓 巨大八爪鱼 2016-1-24 13:08
Notepad++不能正確顯示UTF-16中的輔助平面字符:

但是微軟的記事本卻可以:

而且,在Notepad++的右下角顯示文本文件的編碼格式為USC-2而非UTF-16:

UCS-2是UTF-16的子集。UCS-2不支持輔助平面字符,但是UTF-16既支持基本多語言平面字符,也支持輔助平面字符。

UTF-16 LE BOM:UTF-16小尾序,帶BOM
UTF-16 BE BOM:UTF-16大尾序,帶BOM

內容轉換:

回覆帖子
內容:
用戶名: 您目前是匿名發表。
驗證碼:
看不清?換一張
©2010-2025 Purasbar Ver3.0 [手機版] [桌面版]
除非另有聲明,本站採用知識共享署名-相同方式共享 3.0 Unported許可協議進行許可。