Deno读取Windows终端输入时如何处理重音字符编码问题
Deno Windows CP-1252 命令行输入乱码解决方案
问题原因
Deno默认将标准输入/输出的编码固定为UTF-8,不会自动适配Windows命令提示符的CP-1252编码,因此直接使用prompt()读取输入时,会把CP-1252的字节按UTF-8解码,最终得到乱码字符。
方案1:修改命令提示符编码为UTF-8(推荐)
无需改动代码,每次打开CMD后先执行编码切换命令:chcp 65001
执行后再启动Deno,默认的prompt()方法即可正常读取输入,不会出现乱码。
方案2:手动解码CP-1252编码的输入
如果不想修改CMD默认编码,可以读取stdin原始字节流自行做CP-1252解码,不要使用Deno内置的prompt()方法(该方法返回的是已经被错误解码的字符串,无法还原),参考实现代码如下:
// CP-1252编码映射表,覆盖所有可打印字符 const cp1252Map = new Map<number, string>([ [0x80, '€'], [0x82, '‚'], [0x83, 'ƒ'], [0x84, '„'], [0x85, '…'], [0x86, '†'], [0x87, '‡'], [0x88, 'ˆ'], [0x89, '‰'], [0x8A, 'Š'], [0x8B, '‹'], [0x8C, 'Œ'], [0x8E, 'Ž'], [0x91, '‘'], [0x92, '’'], [0x93, '“'], [0x94, '”'], [0x95, '•'], [0x96, '–'], [0x97, '—'], [0x98, '˜'], [0x99, '™'], [0x9A, 'š'], [0x9B, '›'], [0x9C, 'œ'], [0x9E, 'ž'], [0x9F, 'Ÿ'], [0xA0, ' '], [0xA1, '¡'], [0xA2, '¢'], [0xA3, '£'], [0xA4, '¤'], [0xA5, '¥'], [0xA6, '¦'], [0xA7, '§'], [0xA8, '¨'], [0xA9, '©'], [0xAA, 'ª'], [0xAB, '«'], [0xAC, '¬'], [0xAD, ''], [0xAE, '®'], [0xAF, '¯'], [0xB0, '°'], [0xB1, '±'], [0xB2, '²'], [0xB3, '³'], [0xB4, '´'], [0xB5, 'µ'], [0xB6, '¶'], [0xB7, '·'], [0xB8, '¸'], [0xB9, '¹'], [0xBA, 'º'], [0xBB, '»'], [0xBC, '¼'], [0xBD, '½'], [0xBE, '¾'], [0xBF, '¿'], [0xC0, 'À'], [0xC1, 'Á'], [0xC2, 'Â'], [0xC3, 'Ã'], [0xC4, 'Ä'], [0xC5, 'Å'], [0xC6, 'Æ'], [0xC7, 'Ç'], [0xC8, 'È'], [0xC9, 'É'], [0xCA, 'Ê'], [0xCB, 'Ë'], [0xCC, 'Ì'], [0xCD, 'Í'], [0xCE, 'Î'], [0xCF, 'Ï'], [0xD0, 'Ð'], [0xD1, 'Ñ'], [0xD2, 'Ò'], [0xD3, 'Ó'], [0xD4, 'Ô'], [0xD5, 'Õ'], [0xD6, 'Ö'], [0xD7, '×'], [0xD8, 'Ø'], [0xD9, 'Ù'], [0xDA, 'Ú'], [0xDB, 'Û'], [0xDC, 'Ü'], [0xDD, 'Ý'], [0xDE, 'Þ'], [0xDF, 'ß'], [0xE0, 'à'], [0xE1, 'á'], [0xE2, 'â'], [0xE3, 'ã'], [0xE4, 'ä'], [0xE5, 'å'], [0xE6, 'æ'], [0xE7, 'ç'], [0xE8, 'è'], [0xE9, 'é'], [0xEA, 'ê'], [0xEB, 'ë'], [0xEC, 'ì'], [0xED, 'í'], [0xEE, 'î'], [0xEF, 'ï'], [0xF0, 'ð'], [0xF1, 'ñ'], [0xF2, 'ò'], [0xF3, 'ó'], [0xF4, 'ô'], [0xF5, 'õ'], [0xF6, 'ö'], [0xF7, '÷'], [0xF8, 'ø'], [0xF9, 'ù'], [0xFA, 'ú'], [0xFB, 'û'], [0xFC, 'ü'], [0xFD, 'ý'], [0xFE, 'þ'], [0xFF, 'ÿ'] ]); // CP-1252解码函数 function decodeCp1252(bytes: Uint8Array): string { return Array.from(bytes).map(b => { if (b <= 0x7F) return String.fromCharCode(b); return cp1252Map.get(b) || '�'; }).join('').trim(); } // 自定义支持CP-1252编码的prompt方法 async function cp1252Prompt(message: string): Promise<string> { const encoder = new TextEncoder(); await Deno.stdout.write(encoder.encode(message + ' ')); const buf = new Uint8Array(1024); const readLength = <number>await Deno.stdin.read(buf); return decodeCp1252(buf.subarray(0, readLength)); } // 调用示例 const input = await cp1252Prompt('Insert your character:'); console.log(input); // 输入áé可正常输出对应字符
内容的提问来源于stack exchange,提问作者neves
相关产品推荐
相关产品推荐

