C语言 将预处理器标记转换为字符串

eblbsuwk  于 2023-05-16  发布在  其他
关注(0)|答案(6)|浏览(143)

我正在寻找一种将预处理器标记转换为字符串的方法。
具体来说,我在某处得到了:

#define MAX_LEN 16

我想用它来防止缓冲区溢出:

char val[MAX_LEN+1]; // room for \0
sscanf(buf, "%"MAX_LEN"s", val);

我愿意用其他方法来完成同样的事情,但只能用标准库。

zbwhf8kr

zbwhf8kr1#

参见 Using FILE and LINE to Report Errors

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)

因此,您的问题可以通过执行sscanf(buf, "%" TOSTRING(MAX_LEN) "s", val);来解决。

axzmvihb

axzmvihb2#

我在网上找到了答案。

#define VERSION_MAJOR 4
#define VERSION_MINOR 47

#define VERSION_STRING "v" #VERSION_MAJOR "." #VERSION_MINOR

上面的不起作用,但希望说明我想做的,即。使VERSION_STRING结束为“v4.47”。
要生成正确的数字形式,请使用以下命令

#define VERSION_MAJOR 4
#define VERSION_MINOR 47

#define STRINGIZE2(s) #s
#define STRINGIZE(s) STRINGIZE2(s)
#define VERSION_STRING "v" STRINGIZE(VERSION_MAJOR) \
"." STRINGIZE(VERSION_MINOR)

#include <stdio.h>
int main() {
    printf ("%s\n", VERSION_STRING);
    return 0;
}
xoefb8l8

xoefb8l83#

这应该可以工作:

sscanf(buf, "%" #MAX_LEN "s", val);

如果没有,就需要“双膨胀”技巧:

#define STR1(x)  #x
 #define STR(x)  STR1(x)
 sscanf(buf, "%" STR(MAX_LEN) "s", val);
oyxsuwqo

oyxsuwqo4#

应该使用双展开字符串化宏技巧。或者只是

#define MAX_LEN    16
#define MAX_LEN_S "16"

char val[MAX_LEN+1];
sscanf(buf, "%"MAX_LEN_S"s", val);

并保持同步(这有点麻烦,但只要定义彼此相邻,你就可能记得。
实际上,在这种特殊情况下,strncpy还不够吗?

strncpy(val, buf, MAX_LEN);
val[MAX_LEN] = '\0';

但是,如果是printf,这会更容易:

sprintf(buf, "%.*s", MAX_LEN, val);
nzrxty8p

nzrxty8p5#

虽然前面的一些答案“工作”,但我个人建议只使用简单的字符串API,而不是libc中的dreck。
有许多可移植的API,其中一些还进行了优化,以便于包含在您的项目中。而像ustr这样的一些具有微小的空间开销并支持堆栈变量。

gwbalxhn

gwbalxhn6#

在我的示例中,要生成的格式是%16s%16s%d

#include <iostream>

#define MAX_LEN 16

#define AUX(x) #x
#define STRINGIFY(x) AUX(x)

int main() {
    char buffer[] = "Hello World 25";
    char val[MAX_LEN+1];
    char val2[MAX_LEN+1];
    int val3;

    char format[] = "%" STRINGIFY(MAX_LEN) "s" "%" STRINGIFY(MAX_LEN) "s" "%d";
    int result = sscanf(buffer, format, val, val2, &val3);
    std::cout<< val << std::endl;
    std::cout<< val2 << std::endl;
    std::cout<< val3 << std::endl;
    std::cout<<"Filled: " << result << " variables" << std::endl;
    std::cout << "Format: " << format << std::endl;
}

输出

相关问题