提问人:Kay 提问时间:9/26/2023 最后编辑:Jonathan LefflerKay 更新时间:9/26/2023 访问量:102
C 宏预处理器,用于在字符串中包含数字
C Macro Preprocessor to include a number in string
问:
我想将任意控制代码插入字符串中,但使用十进制数而不是十六进制()或oct()。举一个毫无意义但可以立即理解的例子,我很乐意有一个宏,比如 CC,这样我就可以形成一个字符串:x
\ux
\0x
// Decimal 10 and 13 are ASCII LF and CR resp.
char mystring[] = "This is line 1" CC(10) CC(13) "This is line 2";
最终,此代码将与自定义硬件上的其他非标准函数/行为一起使用。
答:
4赞
chqrlie
9/26/2023
#1
对于十进制数,没有通用的方法可以执行此操作,但如果代码数量有限,则可以使用令牌粘贴:
#include <stdio.h>
#define CC_13 "\x0D"
#define CC_10 "\x0A"
#define CONCAT(a, b) a ## b
#define CC(n) CONCAT(CC_, n)
int main(void) {
// Decimal 13 and 10 are ASCII CR and LF resp.
char mystring[] = "This is line 1" CC(13) CC(10) "This is line 2";
// simple macros are supported too
#define CR 13
#define LF 10
printf("%s" CC(CR) CC(LF), mystring);
return 0;
}
该宏可以与数字和简单宏一起使用,只要将相应的宏定义为字符串常量即可。如果缺少此定义,您将收到一条(有点隐晦的)错误消息。CC
CC_xxx
如果您的目标是嵌入控制字节,那么上述操作应该没问题,尽管有点矫枉过正,因为您可以直接使用宏。CC_xxx
从注释中提供的额外信息来看,您似乎希望将二进制数据嵌入到字符串常量中作为内联命令的参数,这些命令本身被指定为控制代码:为此使用上述技巧会很麻烦,并且指定范围 1..255 之外的数字可能会导致问题,因为您将在这些字符串中嵌入可能被误解的 null 字节。
我建议您将这些参数作为数字字符串传递,以便在运行时在目标设备内进行解析。下面是一个示例:
#define STR(n) #n
#define WHITESPACE(n) "\x1B" STR(n) "F"
char sentence[] = "A big space between here" WHITESPACE(30) "and here."
您可以将此字符串发送到设备,设备处理程序将分析转义字节和 (for forward) 之间的可选数字参数,以向前移动多个像素。使用转义序列只是一个例子,您可以使用最适合您的任何约定,但它允许在服务器端使用以下命令轻松构造字符串:F
printf
#include <stdio.h>
int main(void) {
// Slide in a welcome message
for (int i = 0; i < 100; i++) {
char buf[80];
// CR moves the cursor the beginning of the line
// ESC K erases the rest of the line
// ESC n F moves the cursor right by n pixels
snprintf(buf, sizeof buf, "\r\033K\033%dFHello world!", 100 - i);
send_device(buf);
usleep(1000);
}
return 0;
}
评论
0赞
Kay
9/26/2023
不幸的是,我想要任何数字,因为我想将这些值用作控制代码的参数。例如:有一个附加一个数字的控制代码,以插入一个像素数的空白。WHITESPACE
char sentence[] = "A big space between here" WHITESPACE CC(30) "and here."
2赞
chqrlie
9/26/2023
@Kay:有很大的局限性,但恐怕 C 语言中没有通用的解决方案。另一种方法是在 ASCII 中嵌入参数:用作并在运行时将数字从数字转换为数字,而不是读取字节。#define WHITESPACE(n) "\x01(" #n ")"
char sentence[] = "A big space between here" WHITESPACE(30) "and here."
0赞
Fe2O3
9/26/2023
在这里,我认为支持代码混淆是非常不鼓励的事情。
0赞
Kay
9/26/2023
@chqrlie 这是一个聪明的主意——失去了一些效率,但确实实现了这里其他人拒绝理解的目的。谢谢。
0赞
Fe2O3
9/26/2023
@Kay 您正在寻找的东西可以通过破解源代码来实现......继续,不标准......Gnu 已经预料到你了......printf()
评论
\r\n