Nối int với chuỗi bằng C Preprocessor


90

Tôi đang cố gắng tìm ra cách tôi có thể nối một chuỗi #defineint #define' với một chuỗi' d bằng cách sử dụng C Preprocessor. Trình biên dịch của tôi là GCC 4.1 trên CentOS 5. Giải pháp cũng sẽ hoạt động cho MinGW.

Tôi muốn nối 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 một 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 thấy là một phương pháp trích dẫn các đối số macro, nhưng nó không hoạt động đối với #defines

Điều này không hoạt động.

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

Nó cũng không hoạt động nếu không có #s vì các giá trị là số và nó sẽ mở rộng thành C"/home/user/.myapp" 2 6 không hợp lệ .

Điều này hoạt động, nhưng tôi không thích có cá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 dưới dạng 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

Câu trả lời:


171

Câu hỏi về bộ tiền xử lý C cổ điển….

#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 điều hướng bổ sung sẽ cho phép bộ tiền xử lý mở rộng các macro trước khi chúng được chuyển đổi thành chuỗi.


3
STR () trong trường hợp này sẽ cho 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

5
Tôi không thể nói bao nhiêu lần tôi googled nó và sao chép từ câu trả lời này chính xác, nhưng nó sẽ là ở mức hai con số
MightyPork

1
"STR_HELPER" đầu tiên là bắt buộc vì '#' chỉ hoạt động với đối số macro. Tôi phải mất một lúc để hiểu ra điều đó ..
clarkttfu

1
@clarkttfu, đại loại - có, #chỉ hoạt động với các đối số macro. Tuy nhiên, STR_HELPERmacro là cần thiết để tránh biến macro MAJOR_VERthành chuỗi "MAJOR_VAR", khi chúng ta muốn kết quả như vậy "2".
Lindydancer

13

Một cách làm việc là viết MY_FILE dưới dạng macro tham số:

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

CHỈNH SỬA: Theo ghi nhận của "Lindydancer", giải pháp này không mở rộng macro trong các đối số. Một giải pháp chung 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 tốt nhất, và đơn giản hơn nhiều so với các gợi ý khác. Tôi ngạc nhiên vì nó không được xếp hạng tốt hơn!
osirisgothra

5
Đó là một giải pháp sạch, thật không may, không hoạt động. Nếu đối số được truyền tới MY_FILElà macro, giả sử AB, macro này sẽ mở rộng thành "/home..." "A" "B".
Lindydancer

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)

28
Khiến tôi nhếch mép cười khi mọi người ném Boost vào mọi thứ.
Frerich Raabe

4
@Frerich: Đưa lập luận của bạn lên cao độ, mọi người nên viết trình biên dịch của riêng họ trước tiên bằng mã máy thô, thay vì ném g ++ vào mọi thứ ... Không có ý nghĩa gì để phát minh lại bánh xe. Những lập trình viên giỏi viết mã, những lập trình tuyệt vời thì sử dụng lại.
Maxim Egorushkin

@jonescb: chỉ cần mở tiêu đề tăng cường và tự xem.
Maxim Egorushkin

10
Đúng, tôi đã thử nó. Nó đã hoạt động, nhưng sử dụng tiêu đề Boost trong một chương trình C có vẻ hơi kỳ lạ đối với tôi.
jonescb

1
Oh, xấu của tôi, không nhận thấy Cthẻ.
Maxim Egorushkin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.