2010-03-09 44 views
52

Trong dòng lệnh gcc, tôi muốn xác định một chuỗi như -Dname=Mary, sau đó trong mã nguồn tôi muốn printf("%s", name); để in Mary.
Tôi có thể làm như thế nào?Cách xác định chuỗi ký tự bằng dòng lệnh gcc?

+6

tôi rất khuyên bạn nên sử dụng tất cả-mũ ('-DNAME = \ "Mary \"') cho thẻ mà bạn đang đi để def ine theo cách này, để chúng trông giống như các macro khác. –

+0

Macro trong chuỗi câu hỏi: http://stackoverflow.com/questions/240353/convert-a-preprocessor-token-to-a-string –

Trả lời

61

Hai tùy chọn. Trước tiên, hãy thoát dấu ngoặc kép để vỏ không ăn chúng:

gcc -Dname=\"Mary\" 

Hoặc, nếu bạn thực sự muốn -Dname = Mary, bạn có thể xâu chuỗi nó, mặc dù hơi bị hack.

#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)); 
} 

Lưu ý rằng STRINGIZE_VALUE_OF sẽ vui vẻ đánh giá định nghĩa cuối cùng của macro.

+0

cảm ơn rất nhiều Arthur. bạn phải là chuyên gia trong C. câu hỏi khác: Tôi tán thành tùy chọn thứ hai. khi tôi đang sử dụng STRINGIZE_VALUE_OF (tên), nó dịch nó thành "1", trong trường hợp tôi có gcc -Dname = Mary -DMary. là có anyway để cho gcc ngừng interprite Mary – richard

+0

Richard, sau khi xem xét nhiều tôi không tin rằng tôi có thể đến với một cách mà làm việc trong ví dụ trên. Thật không may, lựa chọn của bạn không mở rộng (ví dụ: cung cấp cho bạn "tên") và mở rộng đầy đủ (ví dụ: name-> Mary-> 1 nếu Mary được định nghĩa là 1). Tùy thuộc vào trường hợp sử dụng chính xác của bạn có thể có những cách xung quanh điều này - nếu Mary có thể trở thành một const int chứ không phải là một định nghĩa, ví dụ. –

+0

cảm ơn một lần nữa. Tôi sẽ đi tùy chọn đầu tiên wuth. – richard

23

để tránh vỏ "ăn" có dấu ngoặc kép và các nhân vật khác, bạn có thể thử dấu nháy đơn, như thế này:

gcc -o test test.cpp -DNAME='"Mary"' 

Bằng cách này bạn có toàn quyền kiểm soát những gì được xác định (dấu ngoặc kép, khoảng trắng, ký tự đặc biệt, và tất cả).

5

Cách di động nhất tôi tìm thấy cho đến nay là sử dụng \"Mary\" - nó sẽ hoạt động không chỉ với gcc mà còn với bất kỳ trình biên dịch C nào khác. Ví dụ, nếu bạn cố gắng sử dụng /Dname='"Mary"' với trình biên dịch của Microsoft, nó sẽ dừng lại với một lỗi, nhưng /Dname=\"Mary\" sẽ hoạt động.

4

Trong Ubuntu, tôi đã sử dụng một bí danh định nghĩa CFLAGS và CFLAGS bao gồm một macro xác định một chuỗi và sau đó tôi sử dụng CFLAGS trong một tệp Makefile. Tôi đã phải thoát khỏi các ký tự trích dẫn kép và cũng là \ ký tự. Nó trông như thế này:

CFLAGS='" -DMYPATH=\\\"/home/root\\\" "' 
+0

chỉ có giải pháp mà thực sự hoạt động – Cyan

+1

Đôi khi, cả hai thoát đơn và gói trong dấu nháy đơn không hoạt động, nhưng điều này đã làm. Lần khác, nó không. Tôi nghĩ rằng sự khác biệt là liệu những lá cờ được đặt trong dấu ngoặc kép tổng thể: '1) định nghĩa = -DLOGPATH = \ "./ logfile \" CFLAGS = -v $ (định nghĩa) .... ' ' 2) DEFINES = -DLOGPATH = \\\ "./ logfile \\\" CFLAGS = "-v $ (DEFINES) ...." ' Sử dụng tùy chọn trình biên dịch-v là hữu ích để xem bộ xử lý trước đang làm gì . – JasonDiplomat

0

FYI: phiên bản Rõ ràng thậm chí khác nhau của toolchain cùng trên cùng một hệ thống có thể hoạt động khác nhau trong vấn đề này ... (Như trong, nó sẽ vẻ đây sẽ là một vấn đề vỏ đi qua, nhưng dường như nó không chỉ giới hạn trong vỏ).

Ở đây chúng ta có xc32-gcc 4.8.3 vs (avr-) gcc 4.7.2 (và nhiều khác) sử dụng makefile cùng và main.c, sự khác biệt duy nhất là 'make CC=xc32-gcc' vv

CFLAGS += -D'THING="$(THINGDIR)/thing.h"' đã được sử dụng trên nhiều phiên bản của gcc (và bash) sau vài năm.

Để thực hiện này tương thích với xc32-gcc (và trong ánh sáng của người khác bình luận tuyên bố rằng \" là xách tay hơn '"), sau đây phải được thực hiện:

CFLAGS += -DTHING=\"$(THINGDIR)/thing.h\" 

ifeq "$(CC)" "xc32-gcc" 
CFLAGS := $(subst \",\\\",$(CFLAGS)) 
endif 

để làm cho mọi việc thực sự là khó hiểu khi phát hiện ra điều này: dường như một kết quả không được kiểm định -D với // kết quả là #define với nhận xét ở cuối ... ví dụ

THINGDIR=/thingDir/ ->#define /thingDir//thing.h ->#define /thingDir

(Cám ơn sự giúp đỡ từ câu trả lời s đây, btw).

-1

Đây là giải pháp của tôi cho: -DUSB_PRODUCT=\""Arduino Leonardo\""
tôi đã sử dụng nó trong một makefile với:
GNU Make 3,81 (từ GnuWin32)

avr-g ++ (AVR_8_bit_GNU_Toolchain_3.5.0_1662) 4.9.2

Các kết quả trong một file biên dịch sẵn (-E lựa chọn cho g ++) là:
const u8 STRING_PRODUCT[] __attribute__((__progmem__)) = "Arduino Leonardo";

Các vấn đề liên quan