在gcc命令行中,我想定义一个字符串,例如-Dname=Mary
,然后在源代码中我希望printf("%s", name);
打印Mary
。
我怎么能这样做?
答案 0 :(得分:80)
两个选项。首先,逃避引号,以便shell不吃它们:
gcc -Dname=\"Mary\"
或者,如果你真的想要-Dname = Mary,你可以将其字符串化,虽然它有点hacky。
#include <stdio.h>
#define STRINGIZE(x) #x
#define STRINGIZE_VALUE_OF(x) STRINGIZE(x)
int main(int argc, char *argv[])
{
printf("%s", STRINGIZE_VALUE_OF(name));
}
请注意,STRINGIZE_VALUE_OF将很乐意评估宏的最终定义。
答案 1 :(得分:24)
为避免shell“吃掉”引号和其他字符,您可以尝试单引号,如下所示:
gcc -o test test.cpp -DNAME='"Mary"'
通过这种方式,您可以完全控制所定义的内容(引号,空格,特殊字符和所有内容)。
答案 2 :(得分:6)
到目前为止,我发现的大多数可移植方式都是使用\"Mary\"
- 它不仅适用于gcc,还适用于任何其他C编译器。例如,如果您尝试将/Dname='"Mary"'
与Microsoft编译器一起使用,则会因错误而停止,但/Dname=\"Mary\"
将起作用。
答案 3 :(得分:5)
在Ubuntu中我使用的是定义CFLAGS的别名,CFLAGS包含一个定义字符串的宏,然后我在Makefile中使用CFLAGS。我不得不逃避双引号字符和\字符。它看起来像这样:
CFLAGS='" -DMYPATH=\\\"/home/root\\\" "'
答案 4 :(得分:1)
这是一个简单的例子:
#include <stdio.h>
#define A B+20
#define B 10
int main()
{
#ifdef __DEBUG__
printf("__DEBUG__ DEFINED\n");
printf("%d\n",A);
#else
printf("__DEBUG__ not defined\n");
printf("%d\n",B);
#endif
return 0;
}
如果我编译:
$gcc test.c
输出:
__DEBUG__ not defined
10
如果我编译:
$gcc -D __DEBUG__ test.c
输出:
__DEBUG__ defined
30
答案 5 :(得分:0)
仅供参考:显然,即使是同一系统上相同工具链的不同版本,在这方面也会有不同的行为...... (因为,它似乎似乎这将是一个shell传递问题,但显然它不仅仅局限于shell)。
这里我们有xc32-gcc 4.8.3与(avr-)gcc 4.7.2(和几个其他)
使用相同的makefile和main.c,唯一的区别是'make CC=xc32-gcc'
等。
CFLAGS += -D'THING="$(THINGDIR)/thing.h"'
已经在许多版本的gcc(和bash)上使用。
为了使其与xc32-gcc兼容(并根据另一条声称“比”更容易“)的评论,必须完成以下工作:
CFLAGS += -DTHING=\"$(THINGDIR)/thing.h\"
ifeq "$(CC)" "xc32-gcc"
CFLAGS := $(subst \",\\\",$(CFLAGS))
endif
使真的在发现这一点时感到困惑:显然,带有//的不带引号的-D导致#define 最后带有注释 ...例如
THINGDIR=/thingDir/
- &gt; #define /thingDir//thing.h
- &gt; #define /thingDir
(感谢您在这里回答 s 的帮助,顺便说一下。)
答案 6 :(得分:0)
我刚刚发现我们的一个应用程序无法在Ubuntu上编译。而且由于Linux和Windows在通用方法上未达成共识,因此我使用了以下方法:
NAME := "Mary"
ifeq ($(SystemRoot),)
# building on another OS
CFLAGS_ADD += -Dname=\"Mary\"
else
# building on Windows
CFLAGS_ADD += -Dname=\\\"Mary\\\"
endif
答案 7 :(得分:0)
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++.exe build active file",
"command": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe",
"args": [
"-g",
"-DSHERAJ",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "compiler: \"C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe\""
}
]
}
我已经在 VS Code 中完成了#define SHERAJ
。它非常适合竞争性编程,因为 -
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#ifdef SHERAJ
freopen("input.txt" , "r", stdin);
#endif
int T;
cin>>T;
for(int test_case = 1;test_case<=T;test_case++) {
cout<<"Hello World"<<endl;
}
}
它适用于 Mac 和 Windows 上的 VS Code。此处描述的其他方法(如 "-Dname=\"SHERAJ\""
和 "-Dname=\\\"SHERAJ\\\""
)对我不起作用。
所以答案是"-DSHERAJ"
答案 8 :(得分:-1)
这是我的解决方案:-DUSB_PRODUCT=\""Arduino Leonardo\""
我在makefile中使用它:
GNU Make 3.81(来自GnuWin32)
和
avr -g ++(AVR_8_bit_GNU_Toolchain_3.5.0_1662)4.9.2
预编译文件中的结果(g ++的-E选项)是:
const u8 STRING_PRODUCT[] __attribute__((__progmem__)) = "Arduino Leonardo";