2018/08/05

UnicodeDecodeError: 'cp932' codec can't decode byte 0x81 in position 8: illegal multibyte sequence (Python3)

参ったなー。

UTF-8で保存したsyugo.txt
を下記コードで読み出そうとしたら、タイトルのエラーが出た。
fr = open("syugo.txt", "rt")
txt = fr.read()
print(txt)
fr.close()

テキストファイルの中身↓
まず、集合について述べる。
ものの集まりを集合と呼ぶ。
例えば、数1と数2からなる集まりは集合であり、
{1, 2}と表す。
1や2をこの集合の要素と言う。

エラーの意味している内容からして、サッパリわからなかったのですが、調べまくりました。
結果から言うと、
「position 8」→8バイト目の次の(9バイト目の)、(16進数=0x)81で始まるところから
cp932(shift-jis)では読み取ることができませんでした。
ってことでした。

UTF-8で書かれた、「まず、集」を16進数で表示すると、
「e381bee3819ae38081e99b86」となります。

>>> import binascii
>>> binascii.b2a_hex(u'まず、集'.encode('utf-8'))
b'e381bee3819ae38081e99b86'

これをshift-jisでデコードしようとしても変換しきれずエラーになるようです。

UTF-8の「ま」は「e381be」となり、これはshift-jisでは「縺セ」とデコードできるので
この場合はエラーになりません。

WindowsのAnacondaではデフォルトではshift-jisでデコードしようとするので
タイトルのエラーとなったようです。

解決方法としては、
「fr = open("syugo.txt", "rt")」

「fr = open("syugo.txt", "rt",encoding="utf-8")」
と、指定してあげれば大丈夫です。


イヤになるくらいハマったなぁ…。。


参考URL:

第4回 UTF-8の冗長なエンコード:本当は怖い文字コードの話|gihyo.jp … 技術評論社
http://gihyo.jp/admin/serial/01/charcode/0004

UTF8 3byte (e3): 
http://orange-factory.com/sample/utf8/code3/e3.html#Hiragana

文字コード表 - 日本語 (シフト JIS) - CP932 - UIC
https://uic.jp/charset/show_raw/cp932/

ゼロからはじめるPython(6) Pythonでファイルを読み書きしよう(その1) ファイル操作基本編 | マイナビニュース
https://news.mynavi.jp/article/zeropython-6/

16進文字列と文字列の変換 - Qiita
https://qiita.com/atsaki/items/6120cad2e3c448d774bf

0 件のコメント: