「記事本」程序的BUG?
打開「記事本」,寫了一個「寫」字,再打開之後發現顯示的是「д」百思不得其解,應該是一個BUG吧?
2014年3月6日補充:首先我對認真回答這個問題的網友表示感謝。但是可能是因為我的問題表述不清,所以在此補充一下。我想問的根本問題是,「記事本」作為Win系統的自帶程序,既沒有避免這種怪異現象的出現,同時也沒有向用戶說明,你使用「記事本"時應該如何如何(比如,你不能只寫一個漢字……),那麼這是否應該視為「記事本」的一個BUG?也就是說,我的問題是:
1.這種現象能否避免,尤其是作為OS自帶的程序2.如果不能避免,是否應該在程序使用說明中事先向用戶聲明程序本身的局限性。
編碼問題。保存的時候默認為ANSI,打開的時候由於notepad是不知道文件用什麼編碼保存的,所以需要進行「猜測」,也就是文件編碼的識別。
一般來說,識別是通過判斷字元範圍實現的。由於UTF-8是遵循UCS-2編碼規律轉換而來,所以字元會有一定特徵:[1]
1. UTF-8 Ascii Chars: 00-7F // 1 Bytes = 0xxxxxxx Multi Bytes: C0-DF + 80-BF // 2 Bytes = 110xxxxx 10xxxxxx E0-EF + 80-BF + 80-BF // 3 Bytes = 1110xxxx 10xxxxxx 10xxxxxx F0-F7 + 80-BF + 80-BF + 80-BF // 4 Bytes = 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx但由於有些CJK字元(例如「寫」的D0B4,以及經典的「聯通」)也能滿足判斷條件,所以就出現錯判的情況。
[1]文本編碼的智能識別其實吧,這確實是個 bug。產生原因大家都懂,我就不廢話了,我只闡述未什麼他是個 bug 而不是個 feature。
記事本默認保存的是 ANSI 編碼,而這個編碼是什麼?我們來看看 Stack overflow 的程序員同行的定義,以及微軟自己的定義:
Stack Overflow 給出的定義:What is ANSI format?微軟自己的定義:ANSI Character Codes Chart我們看到,ANSI 編碼集,微軟認為它就是 CP1252,而眾同行認為所謂 ANSI 標準根本不存在,它只是被微軟誤用(濫用?)為某種低位元組是 7bit,8bit 區域可以為任意編碼集的編碼。
當在記事本裡面輸入了 ANSI 編碼以外的字元(例如中文)時,怎麼辦?對記事本來說,由於它自身無法識別 Unicode 以外的編碼集,所以它應當把它保存為 Unicode(例如 utf-8, ucs2 等等)。
所以現在我的結論是這樣的:
1,記事本無法識別 Unicode 以外的編碼集(當然,其實無人能準確識別),只能通過 BOM 識別 Unicode 類編碼集。2,當輸入中文(CP1252以外的字元)時,記事本沒有保存為 Unicode 而是保存為了 其他的無法被準確識別的編碼(例如GBK),導致了打開文本是可能出現「錯誤識別編碼」的問題
解決方案:記事本對所有 ASCII 以外字元的文本,預設保存為 UTF-8 或者 UCS-2 等等編碼集,如此可以保證打開時被正確識別。(當然,這只是預設值,如果用戶強制用GBK,那bug仍然存在,不過那是用戶的責任了)你寫的字太少了,Windows判斷不出是什麼編碼,所以只能亂猜一個。
謝邀。針對補充的兩個問題作答。
1.這種現象能否避免,尤其是作為 OS 自帶的程序?
編碼問題似乎是無解的。txt 文件是沒有 meta 信息保存區域的,所以編碼只能靠猜;光靠這一個字也猜不對。
我能想到的唯一解決方案是多重擴展名,比如說 abc.utf8.txt 和 def.gb2312.txt,優先採用擴展名中顯式聲明的編碼。(就是類似 tar.gz 和 tar.bz2 的結構。)
2.如果不能避免,是否應該在程序使用說明中事先向用戶聲明程序本身的局限性。
你見過哪個 Bug 是開發者發布的時候就知道的?如果有的話,那叫 Feature,不叫 Bug。關於這個現象的發生細節,具體可以看我09年在看雪發的帖子:
【原創】逆向記事本看UTF8編碼判斷錯誤
http://bbs.pediy.com/showthread.php?t=101120
題主連TXT的文件結構都沒有概念么?TXT是純文本,不保存文本之外的任何信息!記事本打開文本的時候會根據前兩個位元組選擇編碼,如果能用ANSI顯示就不會用其他編碼了。而寫正好是個編碼之後還能用ANSI顯示的。
先來個彩蛋。記事本輸入『聯通』保存,關閉,打開。你會驚喜。
或許這樣說吧,世界上有程序員和非程序員,程序員喜歡從0開始計數,普通人從1開始。然後一個第三方過來看到了5到底是第幾個呢?
也就是編碼方式有多種,但他倆有重合。我來解碼按哪個好呢,這個就看微軟優先選取那個解碼法則吧。
解決辦法,我覺得字多了,他就可以判斷了吧。非得寫一個字元,選格式吧
好多年前學的,也不是學計算機的。可能不全吧
編碼問題.
下次樓主在第一行寫個.log 試試. 這個"bug"更神奇.呵呵
===增訂以回答評論============
在記事本輸入"寫"字, 16進位為 D0 B4.
由於沒有多餘的字元判斷, 系統無法辨識編碼. 如果題主以gb2312編碼打開,則顯示正常中文. 但是win系統是以utf-8編碼打開, 所以杯具了.非win用戶不清楚.是BUG但是考慮到這個問題只在極少的情況下出現,我覺得不做處理也是可以接受的。
這是在Win 10 最新一次更新後做的實驗。這就是微軟給的交代了。另外,除非題主想和微軟打官司,否則這個問題就讓它隨風散去吧
圍牆
偽代碼瞎寫的
=====================================
//輸入法打出來的字用的windows默認編碼,ANSI存了
input()
{
save(ANSI);
}
//記事本只認識unicode,所以打開前先看看是不是用unicode編碼規則編的。如果不符合,就用windows里的編碼表ANSI打開。
//由於「聯通」編碼的特殊性,誤認為是unicode,強行用unicode編碼打開
output()
{
if(firstChar=UNICODE) openAs(UNICODE);
else openAs(ANSI);
}
解決方法就是
1.多打幾個別的字,讓他們不符合unicode編碼規則,記事本就不會任性的非要用unicode去打開了。
2.在存的時候,另存為,選擇unicode編碼格式存,以後用unicode讀就不會錯了。
一個奇怪的問題
新建一個文本文檔,直接打「寫」字,保存後再用記事本打開,就成了「д」,查看十六進位編碼,是「D0 B4 」無誤;但關閉後再打開,刪掉重新寫一個「寫」,保存後重新打開,就正常顯示為「寫」,查看十六進位編碼,成了「EF BB BF E5 86 99 」。不解
BUG確實難免
微軟隱藏了布希的秘密
在任意位置新建一個文本文檔,在文本文檔上打出 「Bush hid the facts」(不含引號) 再保存。
你再打開就會發現——————布希的秘密。
這個秘密在中/英 Windows XP上有效。看看吧!
在中文Windows XP上顯示 「畂桳栠摩琠敨映撿獴」
而在英文Windows XP上顯示18個黑色方塊
原因不知道,但是再給提主補充一個,打開記事本只輸入兩個字「聯通」,保存關閉後也會亂碼
有可能是因為修復這個Bug的代價太高,修復價值也太低導致的,憑心說,這樣一個bug一般而言對正常使用影響並不大,但改好它可能需要增加大量代碼,影響程序效率,這樣一來還不如不去理會。很多設計都會有這樣的考慮的,比如飛機製造業,你總可以做出一個更加快速的引擎,但為此雖要丟失一定的安全性,或更高的成本,在面臨這樣的選擇時,我們遵從「好的設計需要好的妥協」原則,盡量使綜合效果最佳。當然,設計者在知情的情況下,應該向使用者提供說明資料。
推薦閱讀:
※中國大部分人什麼時候可以用上正版 Windows?
※為什麼還會有購買的win10?
※如何看待windows 10不能通過正常方法卸載數個應用商店內的metro應用?
※為什麼SSD能夠使成熟的操作系統的體驗獲得如此多的提升?
※2015年有哪些值得推薦的年度 WP應用?
TAG:MicrosoftWindows |