2010-04-27 15 views
13

जब getopt या getopt_long एक अवैध विकल्प का सामना करना पड़ता है, तो यह optopt में अपमानजनक विकल्प चरित्र को संग्रहीत करता है। जब अवैध विकल्प लंबा विकल्प है, तो मुझे यह पता चल सकता है कि विकल्प क्या था? और क्या कुछ अर्थपूर्ण optopt में संग्रहीत किया जाता है?getopt_long एक अपरिचित विकल्प कहां स्टोर करता है?

मैंने स्वचालित रूप से मुद्रित त्रुटि संदेश को दबाने के लिए opterr = 0 सेट किया है। मैं अपना खुद का संदेश बनाना चाहता हूं कि मैं जहां चाहूं प्रिंट या लॉग कर सकता हूं, लेकिन मैं अपरिचित विकल्प का नाम शामिल करना चाहता हूं।

उत्तर

3

सबसे नज़दीक मुझे मिल सकता है कि अगर आपको BADCH मिलता है तो argv आइटम लौटाएं जो यह argv[optind-1] में है। ऐसा लगता है कि समस्या तर्क खोजने के लिए एक बेहतर तरीका होना चाहिए।

6

आप सही हैं कि मैन पेज इन विवरणों पर सही है, लेकिन स्रोत कोड से पर्याप्त संकेत मिल सकते हैं, उदाहरण के लिए, glibc-x.y.z/posix/getopt.c के _getopt_internal_r में ग्लिब का कार्यान्वयन। (शायद यह है कि इस जीएनयू विस्तार समारोह का ही दिलचस्प कार्यान्वयन है?)

कि कोड सेट optopt जब यह एक गलत लंबे विकल्प है, जो मुझे लगता है कि, जब optopt जाएगा एक गलत कम विकल्प से इस मामले को अलग करने के लिए उपयोगी है का सामना करना पड़ता 0 निश्चित रूप से गैर-एनयूएल हो।

त्रुटि संदेश का उत्पादन किया जब opterr != 0 ज्यादातर argv[optind] के रूप में गलत लंबे विकल्प का प्रिंट लें और बाद में कोड (हमेशा या - परंपरागत ढंग से - कम से कम अधिकतर) बाद में optind लौटने से पहले बढ़ा देता है।

इसलिए इस कार्यक्रम करने पर विचार:

#include <getopt.h> 
#include <stdio.h> 

int main(int argc, char **argv) { 
    struct option longopts[] = { 
    { "foo", no_argument, NULL, 'F' }, 
    { NULL, 0, NULL, 0 } 
    }; 
    int c; 

    do { 
    int curind = optind; 
    c = getopt_long(argc, argv, "f", longopts, NULL); 
    switch (c) { 
    case 'f': printf("-f\n"); break; 
    case 'F': printf("--foo\n"); break; 
    case '?': 
     if (optopt) printf("bad short opt '%c'\n", optopt); 
     else printf("bad long opt \"%s\"\n", argv[curind]); 
     break; 
    case -1: 
     break; 
    default: 
     printf("returned %d\n", c); 
     break; 
    } 
    } while (c != -1); 

    return 0; 
} 

$ ./longopt -f -x --bar --foo
-f
./longopt: अमान्य विकल्प - 'एक्स'
बुरा कम ऑप्ट 'x'
./longopt: गैर मान्यता प्राप्त विकल्प '--bar "
बुरा लंबे ऑप्ट" --bar "
--foo

ऐसे मामलों में

इस प्रकार, optind की पूर्व getopt_long मूल्य कैशिंग द्वारा, हम आसानी से opterr संदेशों के रूप में ही बुरा विकल्प बाहर मुद्रित करने में सक्षम हो।

यह अपने आप ही __nextchar के बजाय argv[optind] की glibc कार्यान्वयन का उपयोग ("गैर मान्यता प्राप्त विकल्प" स्थिति में) के एक अध्ययन के हकदार के रूप में सभी मामलों में बहुत सही नहीं हो सकता है, है, लेकिन यह आप आरंभ करने के लिए पर्याप्त होना चाहिए।

यदि आप optind और getopt_long के दोहराए गए आविष्कारों के बारे में सावधानीपूर्वक सोचते हैं, तो मुझे लगता है कि प्रिंटिंग argv[cached_optind] बहुत सुरक्षित होने जा रही है। optopt मौजूद है क्योंकि छोटे विकल्पों के लिए आपको यह जानने की जरूरत है कि शब्द के भीतर कौन सा चरित्र समस्या है, लेकिन लंबे विकल्पों के लिए समस्या संपूर्ण वर्तमान शब्द है (मॉड्यूलो =param फॉर्म के विकल्प तर्कों को अलग करना)। और वर्तमान शब्द वह है जो getopt_long (आने वाले) optind मान के साथ देख रहा है।

प्रलेखन में लिखी गई गारंटी की अनुपस्थिति में, मैं optopt = 0 व्यवहार का लाभ लेने के बारे में कुछ हद तक कमजोर होगा।

+0

यह आशाजनक प्रतीत होता है, लेकिन इसका परीक्षण करने पर, ऐसा लगता है कि यह समाधान कम से कम मेरे सोलारिस सिस्टम पर 'getopt_long' करता है कि तर्क क्रमपरिवर्तन के प्रति अधिक संवेदनशील है। मैं 'ऑप्टिंड - 1' के साथ चिपक रहा हूँ। –

+0

यदि आप बहुत पसंद करते हैं (मेरे जैसे), तो आप 'char * eq = index (argv [optind-1], '=') के साथ प्रदर्शित करने से पहले पैरामीटर को हटा सकते हैं; अगर (eq! = NULL) * eq = '\ 0'; '। –

संबंधित मुद्दे