Delphi 11中TMemo里UTF-8与ASCII交互控制问题
Delphi TMemo UTF-8显示乱码问题解决
问题现象
- 直接复制粘贴UTF-8文本(比如“Wands!”)到TMemo里,显示完全正常
- 自己生成包含左双引号(UTF-8对应三个字节
0xE2, 0x80, 0x9C)的字符串,用Memo1.Lines.Add(x)添加后,只显示â,而且原字节被转成了0xC3, 0xA2、0xC2, 0x80、0xC2, 0x9C,相当于做了二次编码 - 处理从ePub提取的文本时,因为显示不一致,没法正常生成去重音后的排序版本
核心原因
TMemo的Lines属性默认采用系统ANSI编码处理字符串,而非UTF-8。粘贴文本时,系统剪贴板会自动完成编码转换(把UTF-8转成系统兼容的Unicode/ANSI编码),TMemo拿到的是转换后的正确字符串;但手动添加UTF-8字节时,程序会把这些字节当作普通ANSI字符处理,再重复编码存储,最终导致乱码。
解决方法
1. 直接使用Unicode字符串存储
Delphi中优先用UnicodeString处理内容,避免直接操作字节数组转字符串:
var Utf8Str: UTF8String; begin Utf8Str := UTF8String(#$E2#$80#$9C); // 左双引号的UTF-8表示 Memo1.Lines.Add(string(Utf8Str)); // 转换为UnicodeString后添加 end;
2. 显式解码UTF-8字节数组
如果内容来自字节数组,必须明确用UTF-8解码为UnicodeString后再添加:
var Bytes: TBytes; UnicodeStr: string; begin Bytes := [$E2, $80, $9C]; UnicodeStr := TEncoding.UTF8.GetString(Bytes); Memo1.Lines.Add(UnicodeStr); end;
3. 配置TMemo默认使用UTF-8编码(Delphi XE及以上版本)
直接设置Lines的默认编码为UTF-8,后续添加字符串时确保是解码后的UnicodeString即可:
Memo1.Lines.DefaultEncoding := TEncoding.UTF8;
粘贴正常的本质原因
系统剪贴板在处理UTF-8格式文本时,会自动完成编码适配转换,将UTF-8文本转成TMemo能识别的编码格式,因此粘贴的内容是正确编码的字符串,不会出现乱码。
内容的提问来源于stack exchange,提问作者ChasH
相关产品推荐
相关产品推荐

