在GCC命令行中,我想定义一个字符串,比如-Dname=Mary。然后在源代码中,我希望printf("%s", name);打印Mary。我怎么能这么做呢?
-Dname=Mary
printf("%s", name);
Mary
iecba09b1#
两个选择首先,转义引号,这样shell就不会吃掉它们:
gcc -Dname=\"Mary\"
或者,如果你真的想要-Dname=玛丽,你可以把它字符串化,尽管它有点古怪。
#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将很乐意向下计算到宏的最终定义。
a5g8bdjr2#
为了避免shell“吃掉”引号和其他字符,您可以尝试单引号,如下所示:
gcc -o test test.cpp -DNAME='"Mary"'
这样,您就可以完全控制所定义的内容(引号、空格、特殊字符等)。
py49o6xq3#
到目前为止,我发现的最便携的方法是使用\"Mary\"。它不仅适用于GCC,还适用于任何其他C编译器。例如,如果您尝试在Microsoft编译器中使用/Dname='"Mary"',它将停止并显示错误,但/Dname=\"Mary\"将正常工作。
\"Mary\"
/Dname='"Mary"'
/Dname=\"Mary\"
8ftvxx2r4#
在Ubuntu中,我使用了一个定义CFLAGS的别名,CFLAGS包含了一个定义字符串的宏,然后我在Makefile中使用CFLAGS。我必须转义双引号字符和\字符。它看起来像这样:
CFLAGS='" -DMYPATH=\\\"/home/root\\\" "'
xyhw6mcr5#
这是我的解决方案:**-DUSB_PRODUCT=\""Arduino Leonardo\""**我在一个makefile中使用了它:GNU Make 3.81(来自GnuWin 32)和/或avr-g++(AVR_8_bit_GNU_Toolchain_3.5.0_1662)4.9.2预编译文件的结果(g++的-E选项)是:const u8 STRING_PRODUCT[] __attribute__((__progmem__)) = "Arduino Leonardo";
**-DUSB_PRODUCT=\""Arduino Leonardo\""**
const u8 STRING_PRODUCT[] __attribute__((__progmem__)) = "Arduino Leonardo";
mkh04yzy6#
下面是一个简单的例子:
#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
llycmphe7#
仅供参考:显然,即使是同一系统上同一工具链的不同版本,在这方面也会有不同的表现……(就像,这似乎是一个shell传递问题,但显然它不仅限于shell)。这里我们有xc 32-gcc 4.8.3与(avr-)gcc 4.7.2(和 * 几个 * 其他)使用相同的makefile和main.c,唯一的区别是'make CC=xc32-gcc'等。CFLAGS += -D'THING="$(THINGDIR)/thing.h"'已经在 * 许多 * 版本的gcc(和bash)上使用了好几年。为了使它与xc 32-gcc兼容(并且根据另一条评论声称“比'”更可移植),必须做以下事情:
'make CC=xc32-gcc'
CFLAGS += -D'THING="$(THINGDIR)/thing.h"'
CFLAGS += -DTHING=\"$(THINGDIR)/thing.h\" ifeq "$(CC)" "xc32-gcc" CFLAGS := $(subst \",\\\",$(CFLAGS)) endif
让事情变得 * 真的 * 令人困惑的发现:显然,一个未加引号的-D和一个//会导致一个#define * 和一个注解 * 在最后...例如THINGDIR=/thingDir/ -〉#define /thingDir//thing.h -〉#define /thingDir(谢谢你的回答,顺便说一句)。
THINGDIR=/thingDir/
#define /thingDir//thing.h
#define /thingDir
wgx48brx8#
我刚发现我们的一个应用程序不能在Ubuntu上编译。由于Linux和Windows在通用方法上没有达成一致,我使用了以下方法:
NAME := "Mary" ifeq ($(SystemRoot),) # building on another OS CFLAGS_ADD += -Dname=\"Mary\" else # building on Windows CFLAGS_ADD += -Dname=\\\"Mary\\\" endif
lmvvr0a89#
考虑:
{ "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\"" } ] }
我在Visual Studio Code中完成了#define SHERAJ。它非常适合竞争性编程,因为:
#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上的Visual Studio Code都有效。这里描述的其他方法,如"-Dname=\"SHERAJ\""和"-Dname=\\\"SHERAJ\\\""不适合我。所以答案是"-DSHERAJ"。
"-Dname=\"SHERAJ\""
"-Dname=\\\"SHERAJ\\\""
"-DSHERAJ"
9条答案
按热度按时间iecba09b1#
两个选择首先,转义引号,这样shell就不会吃掉它们:
或者,如果你真的想要-Dname=玛丽,你可以把它字符串化,尽管它有点古怪。
请注意,STRINGIZE_VALUE_OF将很乐意向下计算到宏的最终定义。
a5g8bdjr2#
为了避免shell“吃掉”引号和其他字符,您可以尝试单引号,如下所示:
这样,您就可以完全控制所定义的内容(引号、空格、特殊字符等)。
py49o6xq3#
到目前为止,我发现的最便携的方法是使用
\"Mary\"
。它不仅适用于GCC,还适用于任何其他C编译器。例如,如果您尝试在Microsoft编译器中使用/Dname='"Mary"'
,它将停止并显示错误,但/Dname=\"Mary\"
将正常工作。8ftvxx2r4#
在Ubuntu中,我使用了一个定义CFLAGS的别名,CFLAGS包含了一个定义字符串的宏,然后我在Makefile中使用CFLAGS。我必须转义双引号字符和\字符。它看起来像这样:
xyhw6mcr5#
这是我的解决方案:
**-DUSB_PRODUCT=\""Arduino Leonardo\""**
我在一个makefile中使用了它:
GNU Make 3.81(来自GnuWin 32)
和/或
avr-g++(AVR_8_bit_GNU_Toolchain_3.5.0_1662)4.9.2
预编译文件的结果(g++的-E选项)是:
const u8 STRING_PRODUCT[] __attribute__((__progmem__)) = "Arduino Leonardo";
mkh04yzy6#
下面是一个简单的例子:
如果我编译:
输出:
如果我编译:
输出:
llycmphe7#
仅供参考:显然,即使是同一系统上同一工具链的不同版本,在这方面也会有不同的表现……(就像,这似乎是一个shell传递问题,但显然它不仅限于shell)。
这里我们有xc 32-gcc 4.8.3与(avr-)gcc 4.7.2(和 * 几个 * 其他)使用相同的makefile和main.c,唯一的区别是
'make CC=xc32-gcc'
等。CFLAGS += -D'THING="$(THINGDIR)/thing.h"'
已经在 * 许多 * 版本的gcc(和bash)上使用了好几年。为了使它与xc 32-gcc兼容(并且根据另一条评论声称“比'”更可移植),必须做以下事情:
让事情变得 * 真的 * 令人困惑的发现:显然,一个未加引号的-D和一个//会导致一个#define * 和一个注解 * 在最后...例如
THINGDIR=/thingDir/
-〉#define /thingDir//thing.h
-〉#define /thingDir
(谢谢你的回答,顺便说一句)。
wgx48brx8#
我刚发现我们的一个应用程序不能在Ubuntu上编译。由于Linux和Windows在通用方法上没有达成一致,我使用了以下方法:
lmvvr0a89#
考虑:
我在Visual Studio Code中完成了
#define SHERAJ
。它非常适合竞争性编程,因为:它对我在Mac和Windows上的Visual Studio Code都有效。这里描述的其他方法,如
"-Dname=\"SHERAJ\""
和"-Dname=\\\"SHERAJ\\\""
不适合我。所以答案是
"-DSHERAJ"
。