解決程序中的字符編碼問題

今天臺風(fēng)過境瓮恭,風(fēng)雨交加,突然就想寫一下這個(gè)在學(xué)習(xí)編程初期产还,非常困擾的問題匹厘。
我會盡我所能將這個(gè)問題描述清楚,如果有不當(dāng)之處還請指正雕沉!
轉(zhuǎn)載請注明出處即可



字符與字節(jié)

字符 就是我們平臣牵看得見的這些,比如 '1'坡椒,'c',"中文"尤溜, 在程序代碼中它們往往表現(xiàn)為一個(gè)字符串(其實(shí)字符的范圍要廣得多倔叼,還包括不可見的控制字符,后來出現(xiàn)的 emoj 字符等)

但是我們知道其實(shí)計(jì)算機(jī)內(nèi)部都是只含 01 的二進(jìn)制序列宫莱,于是又引出了兩個(gè)概念
字節(jié) 丈攒,比如 \x31, \xff,它們才是實(shí)際在計(jì)算機(jī)中存儲的東西

而從字符到字節(jié)的映射巡验,就是 字符編碼

ASCII 編碼

這是我們經(jīng)常聽到的編碼际插,在 ASCII 編碼中,可見字符 '1','2','a','f' 或者 控制字符 '\n','\b' 等都被編碼為一個(gè)字節(jié)

其他編碼

其他編碼多種多樣显设,比如 GBK框弛,GB2312 等,它們可以表示漢字捕捂,將每個(gè)漢字編碼為多個(gè)字節(jié)
所以也就出現(xiàn)了所謂 多字節(jié)字符 的概念

使用范圍最廣的應(yīng)該是 UTF-8 編碼瑟枫,它用 1-6 的字節(jié)來編碼世界上所有的字符,包括拉丁字符指攒,中文字符慷妙,西洋字符,emoj 字符等等允悦,幾乎所有

編碼報(bào)錯(cuò)

了解了這些就能理解為什么 編碼出錯(cuò)膝擂,解碼出錯(cuò) 等概念了,亂碼 也是一樣的道理
哪些地方會出現(xiàn)編碼問題呢隙弛?我們分幾個(gè)場景來闡述

  1. 記事本(文本編輯器)

當(dāng)我們將一堆字符敲完了架馋,保存時(shí)文本編輯器一般都會有提示,你想以什么格式保存驶鹉?

舉個(gè)栗子會比較直觀: 我們敲入了 '中文'绩蜻,保存時(shí)選擇 UTF-8 編碼,那么計(jì)算機(jī)內(nèi)部就存儲一個(gè) '\xe4\xb8\xad\xe6\x96\x87'室埋,如果選擇 GBK 編碼办绝,那么就存儲一個(gè) '\xd6\xd0\xce\xc4',這是編碼的過程

相應(yīng)的我們關(guān)閉編輯器后重新打開姚淆,可以選擇以什么編碼格式來打開孕蝉,這就是解碼的過程
所以如果編碼方式和解碼方式不一致,自然就無法將字節(jié)('\xe4\xb8\xad\xe6\x96\x87')轉(zhuǎn)為 我們期望的字符('中文'

了解清楚了么腌逢,然后我們開始擴(kuò)展到更多情景
ps: 不要用記事本寫代碼降淮,容易編碼出錯(cuò)是一方面,主要顯得太 low 了

  1. 我們將字符串賦值給一個(gè)變量搏讶,然后輸出到屏幕

這里除了要保證源代碼文件保存時(shí)的編碼和重新打開時(shí)的編碼一致之外佳鳖,多了一點(diǎn)需要注意

當(dāng)程序運(yùn)行起來的時(shí)候,程序內(nèi)部也有自己的編碼方式(wtf?)媒惕,這里以 python2 為例

python2 內(nèi)部默認(rèn)格式是 unicode 系吩,然而它也允許另外一種格式 str,em...

>>> s = '中文'
>>> s
'\xe4\xb8\xad\xe6\x96\x87'
>>> type(s)
<type 'str'>

可以看到這就是我們的字符串它的類型是 str妒蔚,編碼方式是 UTF-8
所以我們用 UTF-8 來解碼一下穿挨,嗯月弛,得到了一個(gè) unicode 類型,真不錯(cuò)

>>> s.decode('utf-8')
u'\u4e2d\u6587'
>>> type(s.decode('utf-8'))
<type 'unicode'>

python 一定也是這么做的吧
no... 在 python2 中科盛,默認(rèn)使用 ascii 格式來處理的
也就是說帽衙,當(dāng) python2 檢測到該字符串不是 unicode 類型,就嘗試用 ascii 去解碼贞绵,即 s.decode('ascii')
相應(yīng)的厉萝,在輸出的時(shí)候,檢測到該字符串不是 str 類型但壮,就嘗試用 ascii 去編碼

所以你就遇到了這樣兩個(gè)錯(cuò)誤
UnicodeEncodeError: 'ascii' codec can't encode characters
UnicodeDecodeError: 'ascii' codec can't decode characters

對于這個(gè)編碼轉(zhuǎn)換發(fā)生在什么時(shí)候我不太清楚冀泻,知道的請告訴我!
不過這樣下去總不是個(gè)事兒
最好的解決方法就是遷移到 python3 吧(強(qiáng)烈推薦)

python3 統(tǒng)一了字符串表示用 str蜡饵,內(nèi)部存儲用的是 bytes弹渔,默認(rèn)編碼格式是 UTF-8!
更多信息自己去查詢溯祸,這里有點(diǎn)跑偏了

  1. 我們?yōu)g覽網(wǎng)頁的時(shí)候

與上述情況類似肢专,數(shù)據(jù)在網(wǎng)絡(luò)上傳播的形式是 比特流/字節(jié)流,這就意味著還是要編碼

存儲在服務(wù)器的網(wǎng)頁信息(字符)焦辅,在服務(wù)端編碼變成比特流/字節(jié)流博杖,然后我們的瀏覽器拿到這些比特流/字節(jié)流,解碼成(我們實(shí)際看到的)網(wǎng)頁(字符)

編碼解碼不一致就又會亂碼啦筷登!
不過一般網(wǎng)頁都會指定編碼方式 <meta charset="utf-8"/>
瀏覽器也會按指定格式解碼剃根,一般沒事
出錯(cuò)了調(diào)整下瀏覽器編碼方式試試

結(jié)語

差不多就這么多了,點(diǎn)個(gè)關(guān)注嘛..

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末前方,一起剝皮案震驚了整個(gè)濱河市狈醉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌惠险,老刑警劉巖苗傅,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異班巩,居然都是意外死亡渣慕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門抱慌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逊桦,“玉大人,你說我怎么就攤上這事抑进∥捞唬” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵单匣,是天一觀的道長。 經(jīng)常有香客問我,道長户秤,這世上最難降的妖魔是什么码秉? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮鸡号,結(jié)果婚禮上转砖,老公的妹妹穿的比我還像新娘。我一直安慰自己鲸伴,他們只是感情好府蔗,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著汞窗,像睡著了一般姓赤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上仲吏,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天不铆,我揣著相機(jī)與錄音,去河邊找鬼裹唆。 笑死誓斥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的许帐。 我是一名探鬼主播劳坑,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼成畦!你這毒婦竟也來了距芬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤羡鸥,失蹤者是張志新(化名)和其女友劉穎蔑穴,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惧浴,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡存和,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了衷旅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捐腿。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖柿顶,靈堂內(nèi)的尸體忽然破棺而出茄袖,到底是詐尸還是另有隱情,我是刑警寧澤嘁锯,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布宪祥,位于F島的核電站聂薪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蝗羊。R本人自食惡果不足惜藏澳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望耀找。 院中可真熱鬧翔悠,春花似錦、人聲如沸野芒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽狞悲。三九已至撮抓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間效诅,已是汗流浹背胀滚。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留乱投,地道東北人咽笼。 一個(gè)月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像戚炫,于是被迫代替她去往敵國和親剑刑。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354