В командной строке gcc я хочу определить строку, такую как -Dname=Mary
, затем в исходном коде я хочу printf("%s", name);
распечатать Mary
.
Как я могу это сделать?
Как определить строковый литерал в командной строке gcc?
Ответ 1
Два варианта. Сначала избегайте кавычек, чтобы оболочка их не ест:
gcc -Dname=\"Mary\"
Или, если вы действительно хотите -Dname = Mary, вы можете его выровнять, хотя он немного взломан.
#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 с радостью оценит до окончательного определения макроса.
Ответ 2
чтобы избежать "съедания" кавычек и других символов, вы можете попробовать одиночные кавычки, например:
gcc -o test test.cpp -DNAME='"Mary"'
Таким образом, у вас есть полный контроль над тем, что определено (кавычки, пробелы, специальные символы и все).
Ответ 3
Наиболее переносимым способом, который я нашел до сих пор, является использование \"Mary\"
- он будет работать не только с gcc, но и с любым другим компилятором C. Например, если вы попытаетесь использовать /Dname='"Mary"'
с компилятором Microsoft, он остановится с ошибкой, но /Dname=\"Mary\"
будет работать.
Ответ 4
В Ubuntu я использовал псевдоним, который определяет CFLAGS, а CFLAGS включает макрос, который определяет строку, а затем я использую CFLAGS в Makefile. Мне пришлось избегать символов двойной кавычки, а также символов \. Это выглядело примерно так:
CFLAGS='" -DMYPATH=\\\"/home/root\\\" "'
Ответ 5
FYI: По-видимому, даже разные версии одной и той же инструментальной цепочки на одной и той же системе могут действовать по-другому в этом отношении... (Как и в случае, казалось бы, это будет проблема передачи оболочки, но, видимо, она не ограничивается только оболочкой).
Здесь мы имеем xc32-gcc 4.8.3 vs. (avr-) gcc 4.7.2 (и несколько других)
используя тот же make файл и 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
(Спасибо за помощь от ответа s здесь, btw).
Ответ 6
Это мое решение для: -DUSB_PRODUCT=\""Arduino Leonardo\""
Я использовал его в make файле с помощью:
GNU Make 3,81 (от GnuWin32)
и
avr-g++ (AVR_8_bit_GNU_Toolchain_3.5.0_1662) 4.9.2
Результаты в предварительно скомпилированном файле (опция -E для g++): const u8 STRING_PRODUCT[] __attribute__((__progmem__)) = "Arduino Leonardo";