我正在寻找一种方法将预处理器令牌转换为字符串.
具体来说,我在某处得到了:
#define MAX_LEN 16
Run Code Online (Sandbox Code Playgroud)
我想用它来防止缓冲区溢出:
char val[MAX_LEN+1]; // room for \0
sscanf(buf, "%"MAX_LEN"s", val);
Run Code Online (Sandbox Code Playgroud)
我愿意通过其他方式来完成同样的事情,但仅限标准库.
我想将宏扩展的结果字符串化.
我试过以下内容:
#define QUOTE(str) #str
#define TEST thisisatest
#define TESTE QUOTE(TEST)
Run Code Online (Sandbox Code Playgroud)
并且TESTE扩展到:"TEST",而我正试图获得"thisisatest".我知道这是预处理器的正确行为,但任何人都可以帮我找到另一种方法吗?
Using TESTE #TEST is not valid
Using TESTE QUOTE(thisisatest) is not what I'm trying to do
Run Code Online (Sandbox Code Playgroud) 替代标题(以帮助搜索)
- 将预处理程序标记转换为字符串
- 如何从C宏的值创建一个char字符串?
我想在编译时使用C #define来构建文字字符串.
该字符串是为调试,发布等而更改的域.
我想要一些这样的事情:
#ifdef __TESTING
#define IV_DOMAIN domain.org //in house testing
#elif __LIVE_TESTING
#define IV_DOMAIN test.domain.com //live testing servers
#else
#define IV_DOMAIN domain.com //production
#endif
// Sub-Domain
#define IV_SECURE "secure.IV_DOMAIN" //secure.domain.org etc
#define IV_MOBILE "m.IV_DOMAIN"
Run Code Online (Sandbox Code Playgroud)
但预处理器不评估""内的任何内容
当我使用这段代码时:
#include <stdio.h>
#define STR(x) #x
int main(void)
{
printf(__FILE__ STR(__LINE__) "hello!\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它打印
hello.c__LINE__hello!
Run Code Online (Sandbox Code Playgroud)
但是当我使用它时:
#include <stdio.h>
#define STR(x) VAL(x)
#define VAL(x) #x
int main(void)
{
printf(__FILE__ STR(__LINE__) "hello!\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它打印
hello.c7hello!
Run Code Online (Sandbox Code Playgroud)
有什么区别
#define STR(x) #x
Run Code Online (Sandbox Code Playgroud)
和
#define STR(x) VAL(x)
#define VAL(x) #x
Run Code Online (Sandbox Code Playgroud) 我有一些相当通用的代码,它使用预处理器宏将某个前缀添加到其他宏上.这是一个简单的例子:
#define MY_VAR(x) prefix_##x
Run Code Online (Sandbox Code Playgroud)
"prefix_"实际上是在别处定义的,因此每次包含文件时它都会有所不同.它运行良好,但现在我有一些代码我想跳过如果其中一个令牌不存在,但这不起作用:
#if defined MY_VAR(hello)
Run Code Online (Sandbox Code Playgroud)
我希望它扩展到的是:
#ifdef prefix_hello
Run Code Online (Sandbox Code Playgroud)
但我无法弄清楚如何.我需要使用MY_VAR()宏来进行扩展,所以我不能只是对名称进行硬编码.(实际上对于一些测试代码,每次测试一堆类时,相同的代码都包含不同的前缀,我想跳过几个类的几个测试.)
这可能与C++预处理器有关吗?
更新:
这里有一些半可编译的代码可以进一步说明问题:(避免将其压缩到下面的注释中)
#define PREFIX hello
#define DO_COMBINE(p, x) p ## _ ## x
#define COMBINE(p, x) DO_COMBINE(p, x)
#define MY_VAR(x) COMBINE(PREFIX, x)
// MY_VAR(test) should evaluate to hello_test
#define hello_test "blah blah"
// This doesn't work
#ifdef MY_VAR(test)
printf("%s\n", MY_VAR(test));
#endif
Run Code Online (Sandbox Code Playgroud) 我面临一个棘手的问题.我想根据编译器命令行伪造一个C源文件内容.例如(使用VC):
如果我使用命令行
cl -c -E -Dfoo=rice test.c
Run Code Online (Sandbox Code Playgroud)
我希望得到实际的 C内容(在预处理之后):
char *s = "rice";
Run Code Online (Sandbox Code Playgroud)
如果我使用命令行
cl -c -E -Dfoo=ball test.c
Run Code Online (Sandbox Code Playgroud)
我希望得到实际的C源文件内容:
char *s = "ball";
Run Code Online (Sandbox Code Playgroud)
现在找到解决方案......
第一次尝试:
// test.c
#define STRNAME(n) #n
char *s = STRNAME(foo);
Run Code Online (Sandbox Code Playgroud)
- 没运气.无论foo被定义为命令行,我总是得到
char *s = "foo"; // Oh no!
Run Code Online (Sandbox Code Playgroud)
第二次尝试(最接近我可以拍照,但仍然很详细):
// test.c
#define STRNAME(n) #n
char *s = foo;
Run Code Online (Sandbox Code Playgroud)
这次,我必须详细更改命令行:
cl -c -E -Dfoo=STRNAME(rice) test.c
Run Code Online (Sandbox Code Playgroud)
现在我明白了
char *s = "rice";
Run Code Online (Sandbox Code Playgroud)
有没有办法帮助我摆脱这种冗长?
顺便说一句:我真的不喜欢在命令参数中引入引号(让它们成为其中的一部分argv[x],因为你无法在Windows CMD和Linux Bash上可靠且可移植地编写这样的命令行 - 我想.
假设有标志定义,例如:
SHF_WRITE 0x1
SHF_ALLOC 0x2
SHF_EXECINSTR 0x4
SHF_MASKPROC 0xf0000000
Run Code Online (Sandbox Code Playgroud)
给定一个标志,我需要输出SHF_WRITE|SHF_ALLOC比特0x1并0x2打开.
怎么用C做的伎俩?
#define图书馆深处有一个宏,我想快速知道它的确切值。有没有办法将定义的值存储到字符串中以便我可以打印它?
#define intgr 12
#define bnry 0b00000001
#define hex 0x0A
#define str "Hello World"
String myStr;
myStr = intgr;
cout<< myStr << endl; //Simple enough, work no problem
//12 <- actual
//12 <- expected
myStr = bnry; // using "bnry" would not work as #define does not touch inside quotes
cout<< myStr << endl;
//1 <- actual
//0b00000001 <- expected
myStr = hex;
cout<< myStr << endl;
//10 <- actual
//0x0A <- expected
myStr = str;
cout<< myStr << …Run Code Online (Sandbox Code Playgroud)