2012-04-29 15 views
14

यह एक सूचक मेरी main.cके बारे में * argv []

...... 
int main(int argc, char **argv) 
{ 
    init_arg(&argc, &argv); 
    ...... 
} 

यह मेरा init_arg.c

...... 
void init_arg(int *argc, char ***argv) 
{ 
    printf("%s\n", *argv[1]); 
    ...... 
} 

मुझे कोई त्रुटि और चेतावनी के साथ यह संकलक है।

मैं इसे चलाने:

./a.out include

यह मिल विभाजन गलती

जब मैंने इसे डिबग, मैंने पाया कदम printf("%s\n", *argv[1]);

गलत, यह शो:

print *argv[1]

Cannot access memory at address 0x300402bfd

मुझे पता है, init_arg() समारोह में argv[1] मुद्रित करने के लिए कैसे करना चाहते हैं।

+10

+1 डीबगिंग के लिए पहले और इसे अपनी पोस्ट में शामिल करें! – jedwards

+0

जीडीबी में जब आपका कोड दुर्घटनाग्रस्त हो जाता है तो आपके क्रैश तक पहुंचने वाले स्टैक ट्रेस को देखने के लिए कमांड बीटी चलाएं। Http://crasseux.com/books/ctutorial/argc-and-argv.html उदाहरण के लिए सी प्रोग्राम कोड जो प्रोग्राम तर्कों को संभालता है पढ़ें। –

+0

यहां उदाहरणों के साथ एक स्निपेट है [http://pastebin.com/SVAZjsXA ](http://pastebin.com/SVAZjsXA) – dschulz

उत्तर

19

मूल्यांकन के क्रम को बदलने के लिए आपको (* argv) के चारों ओर कोष्ठक की एक जोड़ी जोड़ने की आवश्यकता है। जिस तरह से आपके पास वर्तमान में है, [1] का मूल्यांकन पहले किया जाता है, जो एक अमान्य सूचक उत्पन्न करता है, जिसे तब संदर्भित किया जाता है, जिससे अपरिभाषित व्यवहार होता है।

printf("%s\n", (*argv)[1]); 
+1

या, समकक्ष, आप 'argv [0] [1] 'का उपयोग कर सकते हैं (बस इतना लंबा टाइप करें, लेकिन शायद थोड़ा और पठनीय)। – torek

+7

@torek मैं '(* argv)' के स्थान पर 'argv [0] 'का उपयोग करने से बचना चाहता हूं, क्योंकि पॉइंटर्स की एक सरणी के बजाय," स्केलर "पॉइंटर (यानी एक सरणी के लिए पॉइंटर) में क्या होता है सरणी के लिए। मुझे लगता है कि '(* argv) 'वाक्यविन्यास धारणा को रेखांकित करता है कि हम एक स्केलर के लिए एक सूचक को देख रहे हैं। – dasblinkenlight

+0

स्पष्ट रूप से आप उन लोगों के समूह में आते हैं जो सी बूंदों को भेद बनाए रखना पसंद करते हैं। मुझे सहानुभूति है!1 9 80 के दशक की शुरुआत में, मेरे पास एक सहयोगी था जो सुविधाजनक था कि जो सुविधाजनक था उसके आधार पर हर समय पॉइंटर और सरणी नोटेशन मिश्रण करना पसंद करता था। विशेष रूप से वह चीजें करता है जैसे: 'time_t अब [1]; अब समय); ... '' time_t के बजाय अब; समय (&now); ... '। :-) – torek

13

argv पहले से ही एक सूचक है। बस इसे इस तरह से पारित:

init_arg(&argc, argv); 

और init_arg इस तरह दिखना चाहिए:

void init_arg(int *argc, char **argv) { 
    printf("%s\n", argv[1]); 
} 
+5

यह उत्तर सही है, लेकिन फिर वह 'और argc' के बजाय' argc' भी पास कर सकता है। संभावित रूप से 'और argc' और' और argv' दोनों को पार करने का बिंदु 'init_arg' को संशोधित करने की अनुमति देना है। – torek

+0

आप इन दोनों को इस तरह संशोधित कर सकते हैं। – alf

2

मैं यह सोचते कर रहा हूँ कि इतने है पहली जगह में &argc और &argv पारित करने के लिए कारण यह है कि आप उन्हें अद्यतन कर सकते हैं init_arg के अंदर।

/* 
* init_arg: do something useful with argc and argv, and update argc and argv 
* before returning so that the caller can do something else useful that's 
* not shared with all the other callers of init_arg(). 
* (this comment of course needs updating to describe the useful things) 
*/ 
void init_arg(int *argc0, char ***argv0) { 
    int argc = *argc0; 
    char **argv = *argv0; 
    ... all the operative code goes here, and then ... 
    *argc0 = argc; 
    *argv0 = argv; 
} 
बेशक

इसका मतलब है आप init_arg अंदर जल्दी return रों नहीं करना चाहिए, इसलिए कुछ समझौतों से कर रहे हैं, लेकिन यह सुनिश्चित काम करने के लिए बहुत आसान है: यहाँ कैसे मैं इस तरह के कार्यों में लिखने के लिए पसंद करते हैं, सामान्य रूप में है init_arg के अंदर एक ही नियमित पुराने argc और argv

+1

यदि आप प्रारंभिक वापसी याद करते हैं तो बस एक गोटो का उपयोग करें :) – hugomg

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