You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

含非图形字符的Unbounded_String使用'Image'属性触发编码错误

问题原因

前两行调用Ada.Text_IO.Put_Line直接输出字符串的原始字节序列,不会对内容做UTF-8合法性校验,所以包含Ada.Characters.Latin_1.Reserved_128(十六进制0x80)的字符串能正常输出。

但Unbounded_String'Image属性在生成字符串的可读表示时,GNAT的实现会尝试将内部存储的字节解码为UTF-8格式。而0x80是单独的字节,不符合UTF-8编码规则(UTF-8单字节字符范围是0x00-0x7F,多字节字符的起始字节和后续字节有特定格式),因此触发ADA.STRINGS.UTF_ENCODING.ENCODING_ERROR异常。

解决方案

1. 自定义打印/Image函数绕过UTF验证

如果需要类似'Image的输出格式(比如带引号的字符串表示),可以自己实现函数,直接使用To_String提取原始字节,避免内置'Image的UTF校验:

with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO; use Ada.Text_IO;

function Unbounded_String_Image(US : Unbounded_String) return String is
begin
   return """ & To_String(US) & """;
end Unbounded_String_Image;

-- 使用示例
Put_Line(Unbounded_String_Image(Text_Unbounded_String));

2. 将Latin-1字符转换为合法UTF-8编码

如果需要保留字符语义且兼容UTF-8,可以把Latin_1.Reserved_128(对应Unicode码点U+0080)转换为合法的UTF-8字节序列0xC2 0x80:

Text_String : constant String := "Non Graphic Character: " & Character'Val(16#C2#) & Character'Val(16#80#);

这样Unbounded_String'Image就能正常处理,因为输入是合法的UTF-8。

3. 封装通用打印逻辑简化代码

对于包含Unbounded_String的记录,可以编写通用打印函数,自动处理字段:

with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO; use Ada.Text_IO;

type My_Record is record
   Id : Integer;
   Data : Unbounded_String;
end record;

procedure Print_Record(R : My_Record) is
begin
   Put_Line("Id: " & R.Id'Image);
   Put_Line("Data: """ & To_String(R.Data) & """");
end Print_Record;

这种方式比手动逐个字段处理更简洁,同时避免'Image的UTF校验问题。

内容的提问来源于stack exchange,提问作者dalex78

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 06:35:22