2010-04-16 38 views
20

Tôi gặp sự cố - tôi cần sử dụng giá trị macro dưới dạng chuỗi và làm số nguyên.Xâu chuỗi giá trị macro

#define RECORDS_PER_PAGE 10 

/*... */ 

#define REQUEST_RECORDS \ 
     "SELECT Fields FROM Table WHERE Conditions" \ 
     " OFFSET %d * " #RECORDS_PER_PAGE \ 
     " LIMIT " #RECORDS_PER_PAGE ";" 

char result_buffer[RECORDS_PER_PAGE][MAX_RECORD_LEN]; 

/* ...and some more uses of RECORDS_PER_PAGE, elsewhere... */ 

Điều này không thành công với thông báo về "đi lạC#", tôi đoán tôi sẽ nhận được tên macro được xâu chuỗi chứ không phải giá trị. Tất nhiên tôi có thể cung cấp các giá trị cho phương thức cuối cùng ("LIMIT %d ", page*RECORDS_PER_PAGE) nhưng nó không đẹp và hiệu quả. Đã đến lúc tôi muốn bộ tiền xử lý không xử lý chuỗi theo cách đặc biệt và sẽ xử lý nội dung của họ giống như mã thông thường. Hiện tại, tôi đã cludged nó với #define RECORDS_PER_PAGE_TXT "10" nhưng dễ hiểu, tôi không hài lòng về nó.

Làm cách nào để làm đúng?

+2

Được xử lý chính xác cho tôi trên gcc. – kennytm

+0

Ví dụ về hạt nhân Linux: http://lxr.free-electrons.com/source/include/linux/stringify.h?v=4.7 –

Trả lời

37

Macro xstr được xác định bên dưới sẽ xâu chuỗi sau khi thực hiện mở rộng macro.

#define xstr(a) str(a) 
#define str(a) #a 

#define RECORDS_PER_PAGE 10 

#define REQUEST_RECORDS \ 
    "SELECT Fields FROM Table WHERE Conditions" \ 
    " OFFSET %d * " xstr(RECORDS_PER_PAGE) \ 
    " LIMIT " xstr(RECORDS_PER_PAGE) ";" 
+1

đây có phải là yêu cầu gần đây không? Tôi không nhớ các thủ đoạn như vậy được yêu cầu lần trước tôi đã sử dụng stringification ... – PypeBros

+0

Để tham khảo thêm, mô tả bổ sung về cơ chế (và sắc thái) của stringification (GNU CPP) có tại http://gcc.gnu.org/onlinedocs /cpp/Stringification.html. –

+1

Cập nhật liên kết GCC doc: https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html#Stringizing – eresonance

2

Cố gắng thoát kép trích dẫn của bạn

#define RECORDS_PER_PAGE 10 
#define MAX_RECORD_LEN 10 

/*... */ 
#define DOUBLEESCAPE(a) #a 
#define ESCAPEQUOTE(a) DOUBLEESCAPE(a) 
#define REQUEST_RECORDS \ 
     "SELECT Fields FROM Table WHERE Conditions" \ 
     " OFFSET %d * " ESCAPEQUOTE(RECORDS_PER_PAGE)  \ 
     " LIMIT " ESCAPEQUOTE(RECORDS_PER_PAGE) ";" 

char result_buffer[RECORDS_PER_PAGE][MAX_RECORD_LEN]; 

int main(){ 
    char * a = REQUEST_RECORDS; 
} 

biên dịch cho tôi. Mã thông báo RECORDS_PER_PAGE sẽ được mở rộng bằng cuộc gọi macro ESCAPEQUOTE, sau đó được gửi đến DOUBLEESCAPE để được trích dẫn.

+0

Nhưng nó không thay thế các giá trị phù hợp vì nội dung của # không được đánh giá trước . –

+0

@Mike Quên lối thoát kép –

1
#include <stdio.h> 

#define RECORDS_PER_PAGE 10 

#define TEXTIFY(A) #A 

#define _REQUEST_RECORDS(OFFSET, LIMIT)     \ 
     "SELECT Fields FROM Table WHERE Conditions"  \ 
     " OFFSET %d * " TEXTIFY(OFFSET)     \ 
     " LIMIT " TEXTIFY(LIMIT) ";" 

#define REQUEST_RECORDS _REQUEST_RECORDS(RECORDS_PER_PAGE, RECORDS_PER_PAGE) 

int main() { 
     printf("%s\n", REQUEST_RECORDS); 
     return 0; 
} 

Đầu ra:

SELECT Fields FROM Table WHERE Conditions OFFSET %d * 10 LIMIT 10; 

Lưu ý gián tiếp để _REQUEST_RECORDS để đánh giá các đối số trước stringifying họ.

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