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

如何在C语言u"..."字符串中构造故意UTF-16编码错误

问题原因

C语言标准明确规定,u"..." 类型的char16_t字符串字面量中,不允许直接使用\uXXXX形式的转义写入UTF-16代理区码点(U+D800 ~ U+DFFF区间),编译器在语法校验阶段就会判定这类转义为非法通用字符名,直接抛出编译错误,因此无法通过直接写\ud800这类转义的方式构造包含非法UTF-16编码的测试字符串。
另外原测试代码的注释有误:0xd800属于高代理项,不是低代理项。

可行构造方法

方法1:直接用char16_t数值数组构造(最稳妥、可移植性最高)

非法UTF-16序列本质就是不符合编码规则的16位整数序列,你可以直接按数值写数组,末尾补0x0000作为终止符,和普通u"..."生成的字符串内存布局完全一致,可以直接传入解码函数测试:

#include <uchar.h>

// 未匹配高代理项测试用例
const char16_t test_unmatched_high_surrogate[] = {0xd800, 0x0000};
// 代理顺序颠倒测试用例(低代理在前、高代理在后)
const char16_t test_reversed_surrogate[] = {0xdc01, 0xd802, 0x0000};

这种写法完全绕开了编译器对Unicode转义的合法性校验,不存在兼容问题,是构造错误编码测试用例的首选方案。

方法2:使用十六进制转义\x替代\u转义

编译器不会对\x开头的十六进制转义做Unicode编码合法性校验,你可以直接把代理项的码值写成\x转义形式,放在u"..."字面量中:

// 未匹配高代理项
const char16_t* test_unmatched = u"\xd800";
// 顺序颠倒的代理对
const char16_t* test_reversed = u"\xdc01\xd802";

使用这个方法需要注意:\x转义会贪婪匹配后面所有连续的十六进制字符,如果转义后面紧接其他十六进制字符(0-9、a-f、A-F),需要用字符串字面量拼接截断转义范围,比如要写0xd800后面跟字符'a',要写成u"\xd800""a",避免编译器把'a'也当成转义值的一部分。

注意事项

*不要试图用宏拼接、字符替换等取巧方式绕过编译器对\u转义的校验,这种用法违反C语言标准,不同编译器、不同编译选项下的行为不可预期,没有可移植性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 15:48:45