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

C预处理器如何字符串化含扩展字符(如°)的字符串?

解决Arduino宏字符串化含特殊扩展字符的编译报错问题

问题根源在于avr-gcc的预处理器在处理#__VA_ARGS__字符串化宏时,会将传入内容按C标识符规则解析,而°、¿、¡、«、»这类字符不在合法标识符字符范围内,因此触发报错。以下是几种可行的解决方法:

方案1:使用C++原始字符串字面量(推荐)

avr-gcc 12.2.0支持C++11及以上标准,原始字符串字面量可直接包含特殊字符,无需转义,同时完美兼容条件编译和PROGMEM的RAM节省需求:

#include <Arduino.h>

// 按硬件类型切换不同HTML内容
#if defined(DEVICE_SENSOR_A)
const char htmlRootPage[] PROGMEM = R"(<input name="txtGt" type="number" value="39.5" max="42" step="0.5" style="width:160px;">°C<br>)";
#elif defined(DEVICE_SENSOR_B)
const char htmlRootPage[] PROGMEM = R"(<input name="txtGt" type="number" value="98.6" max="104" step="0.1" style="width:160px;">°F<br>)";
#endif

void setup() {}
void loop() {}

原始字符串用R"(...)"包裹,内部特殊字符直接书写即可,预处理器不会将其当作标识符解析,彻底避开报错,且代码可读性极强。

方案2:转义特殊字符为UTF-8十六进制序列

将报错的特殊字符替换为对应的UTF-8字节转义码,比如:

  • ° → \xC2\xB0
  • ¿ → \xC2\xBF
  • ¡ → \xC2\xA1
  • « → \xC2\xAB
  • » → \xC2\xBB

修改后的代码示例:

#include <Arduino.h>
#define TOSTR_(...) #__VA_ARGS__
#define STRINGIFY(...) TOSTR_(__VA_ARGS__)

const char htmlRootPage[] PROGMEM =
STRINGIFY(<input name="txtGt" type="number" value="39.5" max="42" step="0.5" style="width:160px;">\xC2\xB0C<br>)
;

void setup() {}
void loop() {}

转义序列属于合法的字符串内容,预处理器解析时不会触发标识符错误。

方案3:拆分字符串拼接

把含特殊字符的部分单独定义为PROGMEM字符串,再和宏字符串化的内容拼接,绕过预处理器的标识符检查:

#include <Arduino.h>
#define TOSTR_(...) #__VA_ARGS__
#define STRINGIFY(...) TOSTR_(__VA_ARGS__)

const char degreeSymbol[] PROGMEM = "°";
const char htmlRootPage[] PROGMEM =
STRINGIFY(<input name="txtGt" type="number" value="39.5" max="42" step="0.5" style="width:160px;">)
degreeSymbol
STRINGIFY(C<br>)
;

void setup() {}
void loop() {}

注意这种方式会生成多个独立的PROGMEM字符串,使用时需额外处理拼接逻辑,仅适合无法使用前两种方案的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 17:17:06