Gcc कमांड लाइन में एक स्ट्रिंग शाब्दिक कैसे परिभाषित करें?


80

Gcc कमांड लाइन में, मैं एक स्ट्रिंग को परिभाषित करना चाहता हूं, जैसे -Dname=Maryकि सोर्स कोड में मैं printf("%s", name);प्रिंट करना चाहता हूं Mary
मैं यह कैसे कर सकता था?


8
मैं अत्यधिक अनुशंसा करता हूं कि आप -DNAME=\"Mary\"टोकन के लिए ऑल-कैप्स ( ) का उपयोग करें जो आप इस तरह से परिभाषित करने जा रहे हैं, ताकि वे अन्य मैक्रो की तरह दिखें।
JSB।

स्ट्रिंग प्रश्न में मैक्रो: stackoverflow.com/questions/240353/...
सिरो Santilli郝海东冠状病六四事件法轮功

जवाबों:


97

दो विकल्प। सबसे पहले, उद्धरण चिह्नों से बचें ताकि शेल उन्हें न खाए:

gcc -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 खुशी से एक मैक्रो की अंतिम परिभाषा तक का मूल्यांकन करेगा।


बहुत बहुत धन्यवाद आर्थर। आपको सी में एक विशेषज्ञ होना चाहिए। आगे का प्रश्न: मैं दूसरे विकल्प को मानता हूं। जब मैं STRINGIZE_VALUE_OF (नाम) का उपयोग कर रहा हूं, तो यह "1" में अनुवाद करता है, इस मामले में कि मेरे पास gcc -Dname = Mary -DMary है। वहाँ वैसे भी जाने के लिए है Gcc रोकने के लिए मैरी मैरी
richard

रिचर्ड, बहुत समीक्षा के बाद मुझे विश्वास नहीं हुआ कि मैं एक ऐसा तरीका ले सकता हूं जो उपरोक्त उदाहरण में काम करता है। दुर्भाग्य से, आपकी पसंद कोई विस्तार नहीं है (जैसे आपको "नाम" देता है) और पूर्ण विस्तार (उदाहरण के लिए नाम-> मैरी-> 1 यदि मैरी को 1 के रूप में परिभाषित किया गया है)। आपके सटीक उपयोग के मामले के आधार पर इसके आस-पास के तरीके हो सकते हैं - अगर मैरी एक परिभाषित के बजाय एक कॉन्स्टेंट इंट बन सकती है।
आर्थर शिपकोव्स्की

किसी को भी इस बात का औचित्य दे सकते हैं कि आपको इस तरह के नेस्टेड स्ट्रीफिकेशन मैक्रोज़ का उपयोग करने की आवश्यकता क्यों है? ऐसा लगता है कि परिणाम समान होना चाहिए, लेकिन STRINGIZE_VALUE_OF () को कॉल करना तर्क के स्थूल विस्तार के लिए मजबूर करता है, जबकि STRINGIZE () नहीं करता है।
आयनोकॉस्ट ब्रिघम

1
@IonoclastBrigham, आज तक यह नहीं देखा। इसका एक हिस्सा यह है कि कभी-कभी आप नंगे पासवर्ड को स्ट्रिंग करना चाहते हैं - उदाहरण के लिए, कई मामलों में स्ट्रिंग का उपयोग एस्टर () को लागू करने के लिए किया जाता है, जैसे कि यह आपके पास मौजूद सटीक अभिव्यक्ति को प्रिंट कर सकता है - जिस स्थिति में आप मैक्रोज़ को अनएक्सपैंडेड करना चाहते हैं। एक बार जब आपको यह पता चलता है कि बेस स्ट्राइक इस तरह से काम करता है, तो नेस्टिंग मैक्रो के विस्तार के दूसरे दौर को मजबूर करता है।
आर्थर शिपकोस्की 23

29

उद्धरण और अन्य पात्रों के "खाने" से बचने के लिए, आप इस तरह एकल उद्धरण की कोशिश कर सकते हैं:

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

इस तरह से आपको पूर्ण नियंत्रण है कि क्या परिभाषित किया गया है (उद्धरण, रिक्त स्थान, विशेष वर्ण और सभी)।


8

अब तक मैंने पाया सबसे पोर्टेबल तरीका \"Mary\"- यह न केवल gcc के साथ बल्कि किसी अन्य C कंपाइलर के साथ काम करेगा। उदाहरण के लिए, यदि आप /Dname='"Mary"'Microsoft संकलक के साथ उपयोग करने का प्रयास करते हैं , तो यह एक त्रुटि के साथ बंद हो जाएगा, लेकिन /Dname=\"Mary\"काम करेगा।


6

उबंटू में मैं एक उपनाम का उपयोग कर रहा था जो सीएफएलएजीएस को परिभाषित करता है, और सीएफएलएजीएस में एक मैक्रो शामिल है जो एक स्ट्रिंग को परिभाषित करता है, और फिर मैं सीएफएलएजीएस को मेकफाइल में उपयोग करता हूं। मुझे दोहरे उद्धरण वर्ण और साथ ही \ वर्ण से बचना था। यह कुछ इस तरह देखा गया:

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

2
कभी-कभी, एकल उद्धरणों में बचना और लपेटना दोनों काम नहीं करते थे, लेकिन ऐसा किया गया। दूसरी बार, ऐसा नहीं हुआ। मुझे लगता है कि अंतर यह है कि क्या झंडे समग्र रूप से उद्धरण में रखे गए हैं: 1) DEFINES=-DLOGPATH=\"./logfile\" CFLAGS = -v $(DEFINES).... 2) DEFINES=-DLOGPATH=\\\"./logfile\\\" CFLAGS = "-v $(DEFINES)...." -v संकलक विकल्प का उपयोग यह देखने के लिए उपयोगी है कि प्रीप्रोसेसर क्या कर रहा है।
डेन-जेसन

2

ये रहा एक सरल उदाहरण:

#include <stdio.h>
#define A B+20 
#define B 10
int main()
{
    #ifdef __DEBUG__
        printf("__DEBUG__ DEFINED\n");
        printf("%d\n",A);
    #else
        printf("__DEBUG__ not defined\n");
        printf("%d\n",B);
    #endif
    return 0;
}

अगर मैं संकलन करता हूं:

$gcc test.c

आउटपुट:

__DEBUG__ not defined
10

अगर मैं संकलन करता हूं:

$gcc -D __DEBUG__ test.c

आउटपुट:

__DEBUG__ defined
30

यह परिभाषित करने का एक अच्छा उदाहरण है जिसका उपयोग बुलियन की तरह किया जाता है। हालांकि ओपी ने स्ट्रिंग डिफाइन के बारे में पूछा जो अधिक पेचीदा हैं।
लस्सी

1

यह मेरा समाधान है: -DUSB_PRODUCT=\""Arduino Leonardo\""
मैंने इसे
मेकफाइल में इस्तेमाल किया: GNU मेक 3.81 (GnuWin32 से)
और
avr-g ++ (AVR_8_bit_GNU_Toolchain_3.5.0_1662: 4.9.2

एक precompiled फ़ाइल में परिणाम (जी ++ के लिए विकल्प) है:
const u8 STRING_PRODUCT[] __attribute__((__progmem__)) = "Arduino Leonardo";


0

FYI करें: जाहिरा तौर पर एक ही टूलचैन के विभिन्न संस्करण एक ही सिस्टम पर इस संबंध में अलग तरह से कार्य कर सकते हैं ... (जैसा कि, ऐसा लगता है कि यह एक शेल-पासिंग मुद्दा होगा, लेकिन स्पष्ट रूप से यह केवल शेल तक सीमित नहीं है)।

यहाँ हमारे पास xc32-gcc 4.8.3 बनाम (avr-) gcc 4.7.2 (और कई अन्य) समान मेकफाइल और main.c का उपयोग करके, एकमात्र अंतर है 'make CC=xc32-gcc', आदि।

CFLAGS += -D'THING="$(THINGDIR)/thing.h"'कई पर उपयोग में रहा हैकई वर्षों में gcc (और बैश) के संस्करणों ।

इसे xc32-gcc के साथ संगत बनाने के लिए (और यह दावा करते हुए कि "" की तुलना में अधिक पोर्टेबल है) के बाद, निम्न कार्य करना होगा:

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

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

वास्तव में इसे खोजने में भ्रमित करने वाली चीजें : जाहिरा तौर पर एक unquoted- डी के साथ // परिणाम में एक #define के अंत में एक टिप्पणी के साथ ... उदा।

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

(उत्तर एस यहाँ से मदद के लिए धन्यवाद , btw)।


0

मैंने अभी पाया कि हमारा एक एप्लिकेशन उबंटू पर संकलित नहीं है। चूंकि लिनक्स और विंडोज एक सामान्य दृष्टिकोण पर सहमत नहीं थे, इसलिए मैंने इसका इस्तेमाल किया:

NAME := "Mary"

ifeq ($(SystemRoot),)
    # building on another OS
    CFLAGS_ADD += -Dname=\"Mary\"
else
    # building on Windows
    CFLAGS_ADD += -Dname=\\\"Mary\\\"
endif

0
{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++.exe build active file",
            "command": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe",
            "args": [
                "-g",
                "-DSHERAJ",
                "${file}",
                "-o",
                "${fileDirname}\\${fileBasenameNoExtension}.exe"
            ],
            "options": {
                "cwd": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "compiler: \"C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe\""
        }
    ]
}

मैंने #define SHERAJयहां वीएस कोड में किया है। यह प्रतिस्पर्धात्मक प्रोग्रामिंग के लिए बहुत अच्छा है -

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    #ifdef SHERAJ
        freopen("input.txt"  , "r", stdin);
    #endif
    int T;
    cin>>T;
    for(int test_case = 1;test_case<=T;test_case++) {
        cout<<"Hello World"<<endl;
    }
}

इसने मेरे लिए मैक और विंडोज दोनों पर वीएस कोड के लिए काम किया। अन्य तरीके यहाँ वर्णित हैं "-Dname=\"SHERAJ\""और "-Dname=\\\"SHERAJ\\\""मेरे लिए काम नहीं करते हैं।

तो इसका जवाब है "-DSHERAJ"

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.