[英]How to define a string literal in gcc command line?
在 gcc 命令行中,我想定義一個字符串,例如-Dname=Mary
,然后在源代碼中我想要printf("%s", name);
打印Mary
。
我怎么能做到?
兩種選擇。 首先,對引號進行轉義,這樣 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 會很高興地評估到宏的最終定義。
為避免外殼“吃掉”引號和其他字符,您可以嘗試單引號,如下所示:
gcc -o test test.cpp -DNAME='"Mary"'
這樣您就可以完全控制定義的內容(引號、空格、特殊字符等)。
到目前為止,我發現的最便攜的方法是使用\\"Mary\\"
- 它不僅適用於 gcc,還適用於任何其他 C 編譯器。 例如,如果您嘗試將/Dname='"Mary"'
與 Microsoft 編譯器一起使用,它將因錯誤而停止,但/Dname=\\"Mary\\"
將起作用。
在 Ubuntu 中,我使用了一個定義 CFLAGS 的別名,而 CFLAGS 包含了一個定義字符串的宏,然后我在 Makefile 中使用了 CFLAGS。 我不得不轉義雙引號字符以及 \\ 字符。 它看起來像這樣:
CFLAGS='" -DMYPATH=\\\"/home/root\\\" "'
這是我的解決方案: -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";
這是一個簡單的例子:
#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
僅供參考:顯然,即使是同一系統上相同工具鏈的不同版本在這方面也會有所不同......(就像,這似乎是一個外殼傳遞問題,但顯然它不僅限於外殼)。
這里我們有 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/
-> #define /thingDir//thing.h
-> #define /thingDir
(感謝這里的答案的幫助,順便說一句)。
我剛剛發現我們的一個應用程序無法在 Ubuntu 上編譯。 由於 Linux 和 Windows 在通用方法上沒有達成一致,我使用了這個:
NAME := "Mary"
ifeq ($(SystemRoot),)
# building on another OS
CFLAGS_ADD += -Dname=\"Mary\"
else
# building on Windows
CFLAGS_ADD += -Dname=\\\"Mary\\\"
endif
{
"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"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.