Python, windows console and encodings (cp 850 vs cp1252)

后端 未结 2 1506
忘掉有多难
忘掉有多难 2020-12-13 11:00

I thought I knew everything about encodings and Python, but today I came across a weird problem: although the console is set to code page 850 - and Python reports it correct

2条回答
  •  南方客
    南方客 (楼主)
    2020-12-13 11:33

    I tried the solutions. It may still have some encoding problems. We need to use true type fonts. Fix:

    1. Run chcp 65001 in cmd to change the encoding to UTF-8.
    2. Change cmd font to a True-Type one like Lucida Console that supports the preceding code pages before 65001

    Here's my complete fix for the encoding error:

    def fixCodePage():
        import sys
        import codecs
        import ctypes
        if sys.platform == 'win32':
            if sys.stdout.encoding != 'cp65001':
                os.system("echo off")
                os.system("chcp 65001") # Change active page code
                sys.stdout.write("\x1b[A") # Removes the output of chcp command
                sys.stdout.flush()
            LF_FACESIZE = 32
            STD_OUTPUT_HANDLE = -11
            class COORD(ctypes.Structure):
            _fields_ = [("X", ctypes.c_short), ("Y", ctypes.c_short)]
    
            class CONSOLE_FONT_INFOEX(ctypes.Structure):
                _fields_ = [("cbSize", ctypes.c_ulong),
                ("nFont", ctypes.c_ulong),
                ("dwFontSize", COORD),
                ("FontFamily", ctypes.c_uint),
                ("FontWeight", ctypes.c_uint),
                ("FaceName", ctypes.c_wchar * LF_FACESIZE)]
    
            font = CONSOLE_FONT_INFOEX()
            font.cbSize = ctypes.sizeof(CONSOLE_FONT_INFOEX)
            font.nFont = 12
            font.dwFontSize.X = 7
            font.dwFontSize.Y = 12
            font.FontFamily = 54
            font.FontWeight = 400
            font.FaceName = "Lucida Console"
            handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
            ctypes.windll.kernel32.SetCurrentConsoleFontEx(handle, ctypes.c_long(False), ctypes.pointer(font))
    

    Note: You can see a font change while executing the program.

提交回复
热议问题