2012-09-11 17 views
5

मैं अपने प्रोग्रामिंग क्लास के लिए लिनक्स से सिर और पूंछ कमांड को फिर से बनाने की कोशिश कर रहा हूं। हमने अभी सी का उपयोग शुरू किया है इसलिए मैं स्मृति और पॉइंटर्स आवंटित करने के विचार के लिए नया हूं। मुझे आश्चर्य है कि यह क्यों काम नहीं करता है।सी बेसिक हेड कमांड

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc,char **argv){ 

    /* Checks if correct amount of arguements */ 

    if(argc != 2 || argc != 4){ 
     printf("Usage: %s head <file> \n Or: head <file> -n <number of characters>", argv[0]); 
     exit(-1); 
    } 

    if(strcmp(argv[1], "-n" != 0)){ 
     char fileName[strlen(argv[1])] = argv[1]; 
    } 
} 

//Compile error on char fileName[strlen(argv[1])] = argv[1]; 

कोई अतिरिक्त अंतर्दृष्टि भी सहायक होगी।

+1

'फ़ाइल नाम' भी इसके संलग्न ब्लॉक के अंदर दिखाई देता है, इस मामले में 'if' कथन की सकारात्मक शाखा। – gcbenison

+2

आप केवल उपयोग संदेश देखने जा रहे हैं, क्योंकि यदि 'argc' 2 के बराबर है, तो यह 4 के बराबर नहीं है, और यदि यह 4 के बराबर है, तो यह 2 के बराबर नहीं है, और यदि यह न तो है 2 और न ही 4, फिर ... –

+0

क्या आपने जीसीसी कमांड लाइन पर '-std = c99' निर्दिष्ट किया था? आपको अभी भी एक VLA (चर-लंबाई सरणी) स्वीकार करने के लिए कंपाइलर प्राप्त करने के लिए ऐसा करने की आवश्यकता है। –

उत्तर

2

पहली चीजें पहले, आपका उपयोग आपकी तर्क जांच से मेल नहीं खाता है। उपयोग के अनुसार, आप में से एक का उपयोग करना चाहिए:

head <filename> 
head <filename> -n <count> 

दूसरे शब्दों में, argv[1]हमेशा फ़ाइल नाम है, argv[2] एक है कि -n को निर्धारित करने की आवश्यकता है, तो एक से अधिक दो तर्क हैं।

char *fileName = argv[1]; 

आपको कम से इसे बदलने के लिए की जरूरत नहीं है:

दूसरे, जब तक आप Vlas (चर लंबाई सरणियों) का उपयोग करना चाहते, तो आप शायद अभी फ़ाइल नाम तर्क के लिए एक सूचक की तरह कुछ के साथ स्थापित करना चाहिए सब (आप इसे fopen पर संभवतः पास कर देंगे), इसलिए यह एक और प्रतिलिपि बनाने की कोशिश कर रहा है।

इसके अतिरिक्त, आपके if कथन or के रूप में गलत है, यह and होना चाहिए। यह गारंटी है कि argc या तो 2 नहीं होगा या 4 नहीं होगा, क्योंकि यह दोनों एक ही समय में नहीं हो सकता है।

मैं की तरह कुछ के साथ शुरू होगा:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

static int usage (void) { 
    printf ("Usage: head <file>\n"); 
    printf (" or: head <file> -n <number of characters>\n"); 
    return -1; 
} 

int main (int argc,char *argv[]) { 
    char *fileName; 
    int lineCount; 

    // Checks if correct arguments 

    if ((argc != 2) && (argc != 4)) return usage(); 

    if ((argc == 4) && (strcmp(argv[2], "-n" != 0)) return usage(); 

    // Get file spec and line count 

    fileName = argv[1]; 

    lineCount = (argc == 2) ? 10 : atoi (argv[3]); // or strtol for purists 
    if (linecount < 0) lineCount = 0; 

    // Now go ahead and implement the logic for head. 

} 
+0

और ध्यान दें कि इस दृष्टिकोण के साथ 'fileName' _not_ argv की एक गहरी प्रति है [1] - यह केवल एक सूचक है जो इसकी सामग्री को argv [1] के साथ साझा करता है। यह ठीक है क्योंकि argv [] आमतौर पर कभी नहीं हटाया जाता है। अन्य परिस्थितियों में, यह सी – gcbenison

+2

"आमतौर पर" कभी नहीं छोड़ा गया "गॉथचास" में से एक है? मैं कहूंगा कि "कभी नहीं", कम से कम तब तक 'मुख्य' रिटर्न के बाद (या आपका प्रोग्राम किसी अन्य तरीके से बाहर निकलता है)। – paxdiablo

3

मुझे लगता है कि लिखने के लिए बेहतर है:

char fileName[strlen(argv[1])+1]; 
strcpy(fileName, argv[1]); 

या (यदि आप स्ट्रिंग की एक प्रतिलिपि बनाने के लिए whant नहीं है):

char* fileName = argv[1]; 
+2

जब तक आप प्रतिलिपि को संशोधित नहीं कर रहे हैं, तब तक एक तर्क की एक प्रति बनाने में वास्तव में कोई बात नहीं है, इसलिए आपका दूसरा सुझाव अधिक समझदार है। –

+0

यह स्थिति पर निर्भर करता है? लेखक ने किसी कारण से एक प्रतिलिपि बनाने की कोशिश की, इसलिए, इसे उद्देश्य के साथ बनाया जा सकता है और वह कहीं भी इस स्ट्रिंग को संशोधित करना चाहता है ... – Tutankhamen

+0

'head' के लिए कोड में, फ़ाइल नाम के लिए सबसे व्यावहारिक उपयोग खोलना है यह, और इसके लिए, आपको प्रतिलिपि की आवश्यकता नहीं है (मूल करना चाहिए)। आप सही हैं कि कुछ परिस्थितियों में, नाम की प्रतिलिपि बनाने और संपादित करने की आवश्यकता है। उदाहरण के लिए, यदि आपके पास कुछ प्रकार का 'कंपाइलर' है, तो आप आउटपुट फ़ाइल निर्दिष्ट करने के लिए इनपुट फ़ाइल का विस्तार बदलना चाहेंगे।यदि ऐसा है, तो पूरी स्ट्रिंग की प्रतिलिपि बनाना और प्रतिलिपि बनाना एक अच्छा विचार है क्योंकि आपको अभी भी खुली कॉल और त्रुटि रिपोर्टिंग जैसी चीजों के लिए इनपुट फ़ाइल नाम की आवश्यकता है। –

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