如何对包含扩展字符的字符串进行字符串化,例如度字符° - C预处理器

nbnkbykc  于 2023-05-28  发布在  其他
关注(0)|答案(1)|浏览(300)

How to stringify a string which contains a comma?中描述了如何将字符串字符化。
但是,它不适用于特殊字符,例如:

#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;">°C<br>)
;

void setup() {
}

void loop() {
}

这里的度char °是无效的,我得到

6:99: error: extended character ° is not valid in an identifier
    6 | STRINGIFY(<input name="txtGt" type="number" value="39.5" max="42" step="0.5" style="width:160px;">°C<br>)
      |                                                                                                   ^
exit status 1
extended character ° is not valid in an identifier

只是为了尝试,当我将度char替换为:
p Ψ ψλ𝜋 ω àäâéèêëîöóíùuûES_áñ DE_ß HU_NOK_åæø CZK_úýžáčéěíóřšPL(check accent)_ąććłńśRO_ăâîşRU_яшертыуиопю жьлкйчг дсазхцвбнм
它可以编译。
但是,其他任何其他字符(如
¿¡«»
我得到了相同的编译器错误:扩展字符在标识符中无效。
我可能错了,但在我看来,它应该接受任何utf-8字符(上面的欧洲非英语字符的例子表明它确实如此),直到它匹配STRINGIFY预处理器语句的结束括号,但奇怪的是,有些字符似乎会引起问题。
代码基于ArduinoIDE 1.8.19 https://arduino.github.io/arduino-cli/0.32/sketch-build-process/
编译器如下:

$ avr-gcc -v
Using built-in specs.
Reading specs from /usr/lib/gcc/avr/12.2.0/device-specs/specs-avr2
COLLECT_GCC=avr-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/avr/12.2.0/lto-wrapper
Target: avr
Configured with: /build/avr-gcc/src/gcc-12.2.0/configure --disable-install-libiberty --disable-libssp --disable-libstdcxx-pch --disable-libunwind-exceptions --disable-linker-build-id --disable-nls --disable-werror --disable-__cxa_atexit --enable-checking=release --enable-clocale=gnu --enable-gnu-unique-object --enable-gold --enable-languages=c,c++ --enable-ld=default --enable-lto --enable-plugin --enable-shared --infodir=/usr/share/info --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --prefix=/usr --target=avr --with-as=/usr/bin/avr-as --with-gnu-as --with-gnu-ld --with-ld=/usr/bin/avr-ld --with-plugin-ld=ld.gold --with-system-zlib --with-isl --enable-gnu-indirect-function
Thread model: single
Supported LTO compression algorithms: zlib zstd
gcc version 12.2.0 (GCC)

你为什么需要宏?你不能简单地提供一个实际的字符串吗?
宏,因为它是为物联网上的服务器提供html页面,所以大多数html,css,js代码都是共享的,但#if #else #的使用根据物联网设备和传感器的实际物理硬件而结束。
物联网设备是有限的,特别是与ram(在千字节,而不是PC与千兆字节),我stringify一个所有的html页面,我只是注意到,奇怪的是,有些字符不通过。
因此,二进制代码然后被上传到物联网设备,而不是PC,以供执行。
谢谢

iszxjhcz

iszxjhcz1#

error: extended character ° is not valid in an identifier
C中的标识符由 * 起始字符 *(必须是字母字符,或_字符)组成,后面是更多的字母和/或十进制数字字符。这包括扩展字符集中的所有重音字母字符(如您在问题中所示),但似乎度数符号字符不在所谓的 *alphabetic * 字符集中。它很可能被认为是标点符号字符,因此,它不允许在标识符中使用。
如果您希望代码具有可读性和可移植性,我建议您将自己绑定到ASCII字符集。没有绝对的必要使用国家字符来命名标识符,这会使代码难以阅读(大多数情况下,除了您的区域设置开发人员),并且不会被全球所有编译器安装正确处理。
如果你最终坚持使用国家字符扩展名,你会遇到的一个问题是,你的源文件将不得不到处都带有一个标签,告诉任何人你的源文件是用哪种编码编写的。如果您使用将字符集更改为另一种字符集的编辑器编辑源代码,则可能会导致源代码无法编译(例如:如果您使用utf-8编码,但在编辑过程中将源代码转换为iso-8859-1)

相关问题