windows下的Unicode是UTF-16,每個(gè)字都用兩個(gè)字節(jié)來(lái)表示。編程的時(shí)候,通過(guò)TEXT宏,以及在項(xiàng)目中定義Unicode, _Unicode變量,就可以保證整個(gè)項(xiàng)目都是在Unicode下工作。
現(xiàn)在在將字符串寫(xiě)入文件的時(shí)候,發(fā)生了一些問(wèn)題。寫(xiě)文件用的是WriteFile函數(shù),字符串本身都是UTF-16的,寫(xiě)入文件后發(fā)現(xiàn)用vim和記事本打開(kāi)都無(wú)法正確顯示。用16進(jìn)制的方式查看,每個(gè)字都是對(duì)的,都是2個(gè)字節(jié),如果是英文字母,第二個(gè)字節(jié)就是00。
google了一下,發(fā)現(xiàn)了答案。要在文件開(kāi)頭寫(xiě)入0xfffe,這是Unicode file的identifier,windows下的記事本和寫(xiě)字板讀到這個(gè)頭之后,就能正確識(shí)別這是一個(gè)Unicode文件了。所以,在代碼中,創(chuàng)建文本文件的時(shí)候,要多寫(xiě)這樣一段:
// logfile doesn't exist, create it, that's all
hFile = CreateFile(log_file_path, GENERIC_WRITE, NULL, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
operate_result = FALSE;
} else {
// write 0xfffe at the beginning of the file, this makes Notepad reads Unicodes well
WORD unicode_identifier = 0xfeff;
if (WriteFile(hFile, &unicode_identifier, sizeof(WORD), &bytes_written, NULL)) {
operate_result = TRUE;
} else {
operate_result = FALSE;
}
}
goto finished;
finished:
if (hFile != NULL && hFile != INVALID_HANDLE_VALUE)
CloseHandle(hFile);
return operate_result;
這里不要奇怪為什么設(shè)置給unicode_identifier變量的值是0xfeff,這是因?yàn)?span lang="EN-US">x86是little endian,所以代碼中的oxfeff存在寄存器中,然后設(shè)置到內(nèi)存的時(shí)候,從低地址到高地址就變成了fffe,這樣最后將這個(gè)WORD寫(xiě)入文件之后就正好是fffe了。
最后我自己又測(cè)試了一下,寫(xiě)入中文也是沒(méi)有問(wèn)題的。使用gvim來(lái)打開(kāi)的話需要設(shè)置一下,我在Ubuntu下打開(kāi)文件是OK的,windows下的gvim的.vimrc設(shè)置和Ubuntu一樣的話,應(yīng)該也是沒(méi)問(wèn)題的。