vim 中乱码问题
在Linux下開發(fā),經(jīng)常遇到亂碼問題:shell或者vim中顯示不了中文,或者能夠顯示,但不能輸入中文。每次都是上網(wǎng)去搜,或者同事告訴我一些命令來解決的。一直沒有理解為什么會(huì)出亂碼,本文就是想認(rèn)真分析亂碼問題的原因并找到解決之道。希望本文能夠解決像我這樣的菜鳥在Linux下shell和vim中遇到的亂碼問題。讀者們?nèi)绻x完這篇文章后還是一頭霧水,也不要著急[文章角度不同,不同的人的理解程度也不同],可以多看看類似的文章[文末的參考資料],等多遇到幾次編碼的問題,回頭再看看這些文章,基本就明白了。可以結(jié)合這篇文章一起看?關(guān)于Unicode,字符集,字符編碼,每個(gè)程序員都應(yīng)該知道的事
基本概念
首先得有一些背景概念需要理解一下:
字符[character]
字符代表了字母表中的字符,標(biāo)點(diǎn)符號(hào)和其他的一些符號(hào)。在計(jì)算機(jī)中,文本是由字符組成的。
字符集合[character set]
由一套用于特定用途的字符組成,例如支持西歐語言的字符集合,支持中文的字符集合。字符集合只定義了符號(hào)和他們的語意,其實(shí)跟計(jì)算機(jī)沒有直接關(guān)系。
現(xiàn)實(shí)生活中,不同的語系有自己的字符集合,例如藏文有自己的字符集合,漢文有自己的字符集合。到計(jì)算機(jī)的世界中,也有各種字符集合,例如ASCII字符集合,GB2312字符集合,GBK字符集合。還有一個(gè)其他字符集合的超集--Unicode字符集定義了幾乎絕大部分現(xiàn)存語言需要的字符,是一種通用的字符集,來支持多語言環(huán)境(可以同時(shí)處理多種語言混合的情況)。各個(gè)國(guó)家和地區(qū)在制定編碼標(biāo)準(zhǔn)的時(shí)候,“字符集合”和“字符編碼”一般都是同時(shí)制定的。所以像ASCII字符集合一樣,它也同時(shí)代表了一種字符的編碼。
字符編碼[character encoding]
是一套規(guī)則,定義了在計(jì)算機(jī)內(nèi)存中如何表示字符,是字符集中的每個(gè)字符與計(jì)算機(jī)內(nèi)存中字節(jié)之間的轉(zhuǎn)換關(guān)系,也可以認(rèn)為是把字符數(shù)字化,規(guī)定每個(gè)“字符”分別用一個(gè)字節(jié)還是多個(gè)字節(jié)存儲(chǔ),用哪些字節(jié)來存儲(chǔ)。例如ASCII編碼[你沒看錯(cuò),它既是一種字符集合,也是一種字符編碼],定義了英文字母和符號(hào)在計(jì)算機(jī)中的表示方式,是用一個(gè)字節(jié)來表示。Unicode字符集合,有好幾種字符編碼方式,例如變長(zhǎng)度編碼的UTF8,UTF16等。中文字符集也有很多字符編碼,例如上文提到的GB2312編碼,GBK編碼等。
知乎上的這篇介紹字符編碼,字體,iconv的文章很贊,內(nèi)容淺顯易懂。還有一篇很有名的有關(guān)Unicode和字符集的文章可以看看:The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!),網(wǎng)上有中文版。
之所以產(chǎn)生亂碼,是因?yàn)轱@示的時(shí)候使用的字符編碼方式和實(shí)際內(nèi)容的字符編碼不一致。就跟上文知乎上那個(gè)帖子里的小姑娘和小男孩的例子一樣,顯示所用的字符編碼和實(shí)際內(nèi)容的字符編碼方式不一致,自然就看不懂對(duì)方寫的是啥。所以想正確顯示內(nèi)容,有兩個(gè)方法:
1. 統(tǒng)一一下,雙方都使用同一種編碼方式。 2. 把對(duì)方的內(nèi)容轉(zhuǎn)換成跟自己的編碼方式一致的內(nèi)容。可以用類似 iconv 這樣的工具來完成其次,還需要了解Linux系統(tǒng)中的這個(gè)東東:
語系locale
可以通過命令:?locale -a?來顯示當(dāng)前Linux系統(tǒng)支持的所有的語言環(huán)境。關(guān)于locale,強(qiáng)烈推薦看看Locale 詳解,然后搞明白以下三個(gè)環(huán)境變量的優(yōu)先級(jí):LC_ALL>LC_*>LANG。locale相關(guān)的各個(gè)環(huán)境變量的作用參見這里。
亂碼實(shí)戰(zhàn)
有了以上的知識(shí)儲(chǔ)備,就可以解決以下問題了:
登錄終端中顯示的亂碼問題
用ssh客戶端putty/securecrt 登錄遠(yuǎn)程Linux服務(wù)器舉例子:
要顯示中文,首先確保bash中設(shè)置的語系是支持中文的,例如采用zh_CN.UTF8編碼。可以簡(jiǎn)單的使用命令:export LANG=zh_CN.UTF8?來設(shè)置。如果此時(shí)putty中中文仍然是亂碼,說明putty自身設(shè)置的編碼跟剛才設(shè)置LANG的編碼方式不一樣,把putty中的編碼方式改成UTF8。之后就可以顯示并輸入中文了。 如果你用的是bash,可以在~/.bashrc?配置文件中加入上述的命令。這樣就不用每次登錄后手動(dòng)設(shè)置系統(tǒng)編碼了。
vim中顯示的亂碼問題
在vim中,有以下幾個(gè)環(huán)境變量要理解[可以在vim中使用 :help 關(guān)鍵詞 來查看文檔]:
1. termencodingEncoding used for the terminal. This specifies what character encoding the keyboard produces and the display will understand. For the GUI it only applies to the keyboard. 終端使用的編碼方式,指定了鍵盤輸出的編碼格式和屏幕能夠正常顯示的編碼方式 2. encoding Sets the character encoding used inside Vim. It applies to text in the buffers, registers, Strings in expressions, text stored in the vim info file, etc. Changing this option will not change the encoding of the existing text in vim. The character encoding of files can be different from 'encoding'. This is specified with 'file encoding'. The conversion is done with icon() or as specified with ‘charconvert' 設(shè)置了vim內(nèi)部緩沖區(qū)、寄存器、表達(dá)式等中存儲(chǔ)的文本的編碼方式。它與文件的編碼 [ fileencoding ] 可以是不一樣的。如果不一樣,中間會(huì)經(jīng)過iconv 轉(zhuǎn)換 如果工作用的編碼中含有無法轉(zhuǎn)換為內(nèi)部編碼的字符,在這些字符就會(huì)丟失。因此,在選擇 Vim 的內(nèi)部編碼的時(shí)候,一定要使用一種表現(xiàn)能力足夠強(qiáng)的編碼,例如UTF8,以免影響正常工作。 3. fileencoding Sets the character encoding for the file of this buffer. When 'file encoding' is different from 'encoding', conversion will be done when reading and writing the file.文件自身的編碼方式。如果fileencoding和encoding不一致,那么在讀取和寫入文件時(shí),會(huì)對(duì)編碼方式進(jìn)行轉(zhuǎn)換。 通過打開文件后設(shè)置 fileencoding,我們可以將文件由一種編碼轉(zhuǎn)換為另一種編碼 4. fileencodings This is a list of character encodings considered when starting to edit an existing file. When a file is read, Vim tries to use the first mentioned character encoding. If an error is detected, the next one in the list is tried. When an encoding is found that works, 'file encoding' is set to it. If all fail, 'file encoding' is set to an empty string, which means the value of 'encoding' is used. Note that 'fileencodings' is not used for a new file, the global value of 'file encoding' is used instead. 是一個(gè)字符編碼的列表。當(dāng)vim打開一個(gè)文件時(shí),會(huì)嘗試使用列表中的第一個(gè)字符編碼方式。如果檢測(cè)到錯(cuò)誤,就用列表中的下一個(gè)。當(dāng)找到一個(gè)可以正常工作的字符編碼方式后,file encoding就被設(shè)置成找到的字符編碼方式。如果最后都失敗了,fileencoding就被設(shè)置成空的,這意味者字符的編碼方式就跟 encoding變量的值一樣了。 這樣通過這個(gè)列表,Vim可以自動(dòng)判斷文件的編碼,自動(dòng)判斷失敗時(shí)還可手動(dòng)設(shè)定 fileencoding 來指定編碼。因此,設(shè)置 fileencodings 的時(shí)候,一定要把要求嚴(yán)格的、當(dāng)文件不是這個(gè)編碼的時(shí)候更容易出現(xiàn)解碼失敗的編碼方式放在前面,把寬松的編碼方式放在后面。當(dāng)vim中遇到亂碼時(shí),基本都是由于vim沒有能夠正確地識(shí)別出文件的編碼導(dǎo)致的。
首先保證終端里可以正常顯示中文,然后使用命令?:set fileencoding=GBK?來設(shè)置vim中此文件的正確編碼。可以使用命令?:set fileencoding?查看vim識(shí)別出的文件編碼。
轉(zhuǎn)載于:https://www.cnblogs.com/wang985850293/p/5623918.html
總結(jié)
- 上一篇: JavaScript中Exists函数
- 下一篇: 没学历最吃香的职业 可以考虑这几个