用萬國碼寫C++程式


首先我先給個簡單的結論
「盡量使用UTF-8,不管是在Windows還是Linux」

寬字元這個字眼泛指UTF-16以上的編碼方式(UTF-16、UTF-32等等),UTF-8不用寬字元來儲存,使用C語言原本就有的char便可。


sizeof(char)==1
sizeof(wchar_t)==2 Windows下的寬字元
sizeof(wchar_t)==4 Linux下的寬字元


使用UTF-8的情況
char *str= u8"ToyBox" u8"玩具"
sizeof(str) 7
(6個字母加結尾)
5
(兩個中文字加結尾)
strlen(str) 6
(正確)
4
(誤判了)











在UTF-8裡面,一個中文字元佔2byte以上,所以不能用strlen()來判斷字數。

※如果你在程式碼寫 L"玩具" 會當成是萬國碼寬字元
而只寫 "玩具"前面沒補上L的話會被GCC當UTF-8處理
但是 Visual Studio 是依OS語系來轉換,台灣這邊就是當成BIG5編碼了
C++11有提供新的寫法 u8"玩具" 來指定編譯器要以UTF-8處理


下面是Windows下的寬字元


Windows下的寬字元
wchar_t *str= L"ToyBox" L"玩具"
sizeof(str) 14
(每個字元都佔2byte)
6
(兩個中文字加結尾)
strlen(str) 6
(正確)
2
(正確)











上面只是個例子,萬國碼有可能一個字就超過2byte,所以連Windows下的 wchar_t都無法正確計算字數,所以如果想要讓每個字都佔有相同的大小,你必須選擇UTF-32才夠大,使用寬字元的好處就是計算字數很容易,要個別讀字碼也很輕鬆。 


UTF-8的最大好處在於它可沿用ansi key code的處理方式,像 fopen() 就不用改成 wfopen() 這怪樣子(更別說不同的編譯器可能還會有不同的名字),所以不支持萬國碼的舊版lua照樣可以接受UTF-8字串。

UTF-8有分「檔頭含BOM」跟「檔頭不含BOM」兩種
含BOM這種是微軟想出來的
不含BOM這種才是真正的UTF-8


大致上比較起來,不含BOM會是比較好的選擇,但可能是為了配合微軟,大多數場合對於含不含BOM並不在意,像是python、gcc、lua都不介意


帶有BOM的UTF-8 沒有BOM的UTF-8
缺點 1.CMake的組態檔不接受這種編碼
2.php也不吃這個
3.即使只寫英文也無法被當成ansi文件
4.NetBeans的Breadcrumbs會失效
1.這種程式碼在Visual Stduio不能除錯









最後誠心建議以UTF-8為主就好,我過去寫的程式為了兼容UTF-8跟寬字元真的多寫了很多東西,現在都以UTF-8為主,必要時才轉為寬字元。

lua API



堆疊頂部元素索引為-1
堆疊底部元素索引為1

最新push進去的元素是位在索引-1

lua的特有結構table可以當做std::map來看待就好,使用
上都是key-value的概念


lua_pushvalue(lua_State *L, int index)
將該索引位置的元素複製到堆疊頂部

lua_pop(lua_State *L, int num)
將頂部num個元素刪掉

lua_getglobal(lua_State *L,const char* name)
從全域table取出指定名稱(key)的成員

lua_setglobal(lua_State *L,const char* name)
將堆疊頂部元素取個名字然後塞進全域table

lua_getfield(lua_State *L, int index, const char* name)
從指定索引(table)取出指定名稱(key)的成員,這不是一種複製,對取出成員所做的行為會執行在指定索引的該成員

lua_setfield(lua_State *L, int index, const char* name)
將堆疊頂部元素取個名字然後塞進指定索引(table)

lua_gettable(lua_State *L, int index)
將該索引位置的元素(table)複製出來,取代堆疊頂部元素,原本的頂部元素則成為table成員

lua_settable(lua_State *L, int index)
將索引-1當作value,索引-2當作key,塞入指定元素(table)

lua_newtable(lua_State *L)
新增一個空table到堆疊頂部

lua_pushnil(lua_State *L)
新增一個空值到堆疊頂部

lua_insert(lua_State *L, int index)
將堆疊頂部元素插進指定位置