2011-03-28 68 views
57

Tôi đang cố gắng tìm ra cách tôi có thể nối một chuỗi d #define 'd int đến một #define' bằng cách sử dụng Bộ xử lý trước C. Trình biên dịch của tôi là GCC 4.1 trên CentOS 5. Giải pháp cũng nên làm việc cho MinGW.Nối chuỗi int bằng chuỗi bằng cách sử dụng Bộ tiền xử lý trước

Tôi muốn nối thêm một số phiên bản vào một chuỗi, nhưng cách duy nhất tôi có thể làm cho nó hoạt động là tạo bản sao của số phiên bản được định nghĩa là chuỗi.

Điều gần nhất tôi có thể tìm được một phương pháp trích lập luận vĩ mô, nhưng nó không làm việc cho #define s

Đây là không hoạt động.

#define MAJOR_VER 2 
#define MINOR_VER 6 
#define MY_FILE "/home/user/.myapp" #MAJOR_VER #MINOR_VER 

Nó không làm việc mà không có sự # s hoặc vì giá trị là số và nó sẽ mở rộng tới "/home/user/.myapp" 2 6, đó là không hợp lệ C.

Tính năng này hoạt động, nhưng tôi không thích có bản sao của phiên bản được xác định bởi vì tôi cũng cần chúng làm số.

#define MAJOR_VER 2 
#define MINOR_VER 6 
#define MAJOR_VER_STR "2" 
#define MINOR_VER_STR "6" 
#define MY_FILE "/home/user/.myapp" MAJOR_VER_STRING MINOR_VER_STRING 
+3

Bản sao có thể có của [Chuyển đổi mã thông báo tiền xử lý thành chuỗi] (http://stackoverflow.com/questions/240353/convert-a-preprocessor-token-to-a-string) –

Trả lời

97

cổ điển C Preprocessor câu hỏi ....

#define STR_HELPER(x) #x 
#define STR(x) STR_HELPER(x) 

#define MAJOR_VER 2 
#define MINOR_VER 6 
#define MY_FILE "/home/user/.myapp" STR(MAJOR_VER) STR(MINOR_VER) 

Mức thêm về mình sẽ cho phép tiền xử lý để mở rộng các macro trước chúng được chuyển thành chuỗi.

+2

Cảm ơn. Điều này làm việc, và nó là một giải pháp rất sạch sẽ. – jonescb

+0

STR() trong trường hợp này sẽ cung cấp một chuỗi hẹp. Có một biến thể để chuyển đổi này thành một chuỗi rộng không? – gkns

2

Bạn có thể làm điều đó với BOOST_PP_STRINGIZE:

#define MAJOR_VER 2 
#define MINOR_VER 6 
#define MY_FILE "/home/user/.myapp" BOOST_PP_STRINGIZE(MAJOR_VER) BOOST_PP_STRINGIZE(MINOR_VER) 
+20

Làm cho tôi cười cách mọi người ném Boost vào mọi thứ. –

+4

@Frerich: Lấy lập luận của bạn đến cùng cực, mọi người nên viết trình biên dịch riêng của họ đầu tiên trong mã máy thô, thay vì ném g ++ vào mọi thứ ... Không có điểm nào để phát minh lại bánh xe. Tốt lập trình viết mã, những người tuyệt vời tái sử dụng. –

+0

@jonescb: chỉ cần mở [tiêu đề tăng] (http://svn.boost.org/svn/boost/trunk/boost/preprocessor/stringize.hpp) và tự mình xem. –

8

Một cách làm việc là viết MY_FILE như một macro tham số:

#define MY_FILE(x,y) "/home..." #x #y 

EDIT: Theo ghi nhận của "Lindydancer", giải pháp này không mở rộng macro trong lập luận. Giải pháp tổng quát hơn là:

#define MY_FILE_(x,y) "/home..." #x #y 
#define MY_FILE(x,y) MY_FILE_(x,y) 
+1

Theo ý kiến ​​trung thực của tôi, đây là câu trả lời hay nhất và đơn giản hơn nhiều so với các đề xuất khác. Tôi ngạc nhiên vì nó không được xếp hạng tốt hơn! – osirisgothra

+3

Đó là một giải pháp sạch, thật không may, không hoạt động. Nếu đối số được chuyển đến 'MY_FILE' là các macro, hãy nói 'A' và' B', macro này sẽ mở rộng thành '"/home ... "" A "" B "'. – Lindydancer

+1

Đúng, nhưng có một cách giải quyết nổi tiếng (xem chỉnh sửa). –

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