2008-09-04 23 views
44

मुझे एक उपयोगिता मिली है जो किसी गेम द्वारा आवश्यक फ़ाइलों की एक सूची आउटपुट करता है। मैं एक सी प्रोग्राम के भीतर उस उपयोगिता को कैसे चला सकता हूं और इसके आउटपुट को कैसे पकड़ सकता हूं ताकि मैं उसी कार्यक्रम में इस पर कार्य कर सकूं?मैं सी से बाहरी प्रोग्राम कैसे चला सकता हूं और इसके आउटपुट को पार्स कर सकता हूं?

अद्यतन: जानकारी की कमी पर अच्छी कॉल। उपयोगिता तारों की एक श्रृंखला को थूकती है, और यह मैक/विंडोज/लिनक्स में पूर्ण पोर्टेबल माना जाता है। कृपया ध्यान दें, मैं उपयोगिता निष्पादित करने और इसके आउटपुट को बनाए रखने के लिए एक प्रोग्रामेटिक तरीका ढूंढ रहा हूं (जो stdout पर जाता है)।

+0

यह भी देखना http://stackoverflow.com/questions/125828/capturing-stdout-from-a-system-command-optimally – rogerdpack

+0

हैं आप stderr चाहते हैं साथ ही आप रीडायरेक्ट कर सकते हैं, उदाहरण के लिए कॉल ls nonexistant-name 2> और 1 – Vic

+5

यह डुप्लिकेट नहीं है; लिंक किया गया प्रश्न ** सी ++ विशिष्ट ** है, जबकि यह प्रश्न ** सी ** है। –

उत्तर

45

यूनिक्स-आईएसएच वातावरण में साधारण समस्याओं के लिए popen() आज़माएं।

आदमी पृष्ठ से:

popen() फ़ंक्शन एक पाइप बनाने, forking और खोल लागू द्वारा एक प्रक्रिया खोलता है।

यदि आप रीड मोड का उपयोग करते हैं तो यह वही है जो आपने पूछा था। मुझे नहीं पता कि यह विंडोज में लागू किया गया है या नहीं।

अधिक जटिल समस्याओं के लिए आप इंटर-प्रोसेस संचार देखना चाहते हैं।

+20

'popen()' का सही तरीके से उपयोग करने के तरीके के कुछ उदाहरण अच्छे होंगे। –

+1

मैंने फ़ंक्शन के लिए ओपन ग्रुप मैन पेज पर एक लिंक जोड़ा है, जिसमें एक उदाहरण शामिल है। असल में 'पॉपन' आपको एक फ़ाइल पॉइंटर बहुत अधिक 'fopen' की तरह देता है। यह सिर्फ इतना है कि यह आपको मानक इनपुट को लिखने या डिस्क फ़ाइल के साथ बातचीत करने के बजाय प्रोग्राम के मानक आउटपुट से पढ़ने देता है। यह यूनिक्स का * * सब कुछ एक फाइल है "* काम पर दर्शन। कुछ कार्यान्वयन द्वि-दिशात्मक संचार की अनुमति देकर मानक का विस्तार करते हैं। – dmckee

+0

[थाई एस उत्तर] (http://stackoverflow.com/a/53372/119527) इंगित करता है कि 'पॉपन' विंडोज पर उपलब्ध है। –

7

ठीक है, मानते हैं कि आप विंडोज वातावरण में कमांड लाइन पर हैं, आप पाइप या कमांड लाइन रीडायरेक्ट का उपयोग कर सकते हैं। उदाहरण के लिए,

commandThatOutputs.exe > someFileToStoreResults.txt 

या

commandThatOutputs.exe | yourProgramToProcessInput.exe 

अपने कार्यक्रम के भीतर, आप सी मानक इनपुट कार्यों का उपयोग अन्य कार्यक्रमों निर्गम (scanf, आदि) को पढ़ने के लिए कर सकते हैं: http://irc.essex.ac.uk/www.iota-six.co.uk/c/c1_standard_input_and_output.asp। आप फ़ाइल उदाहरण का भी उपयोग कर सकते हैं और fscanf का उपयोग कर सकते हैं। यह यूनिक्स/लिनक्स में भी काम करना चाहिए।

यह एक बहुत ही सामान्य सवाल है, आप अधिक विवरण शामिल करना चाहेंगे, जैसे कि यह किस प्रकार का आउटपुट है (बस टेक्स्ट, या बाइनरी फाइल?) और आप इसे कैसे संसाधित करना चाहते हैं।

संपादित करें: हुरे स्पष्टीकरण!

एसटीडीओटीटी को पुनर्निर्देशित करना परेशानी लग रहा है, मुझे इसे .NET में करना पड़ा, और उसने मुझे सभी प्रकार के सिरदर्द दिए। ऐसा लगता है कि उचित सी तरीका एक बच्चे की प्रक्रिया को जन्म देना है, एक फाइल पॉइंटर प्राप्त करना है, और अचानक मेरे सिर को दर्द होता है।

तो एक हैक है जो अस्थायी फ़ाइलों का उपयोग करता है। यह आसान है, लेकिन यह काम करना चाहिए। अगर गति कोई मुद्दा नहीं है (डिस्क धीमा हो रही है), या अगर यह फेंक दिया जाता है तो यह अच्छी तरह से काम करेगा। यदि आप एक एंटरप्राइज़ प्रोग्राम बना रहे हैं, तो एसटीडीओटी रीडायरेक्शन की तलाश करना शायद सबसे अच्छा है, अन्य लोगों ने सिफारिश की है।

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

int main(int argc, char* argv[]) 
{ 
    FILE * fptr;     // file holder 
    char c;       // char buffer 


    system("dir >> temp.txt");  // call dir and put it's contents in a temp using redirects. 
    fptr = fopen("temp.txt", "r"); // open said file for reading. 
            // oh, and check for fptr being NULL. 
    while(1){ 
     c = fgetc(fptr); 
     if(c!= EOF) 
      printf("%c", c);  // do what you need to. 
     else 
      break;     // exit when you hit the end of the file. 
    } 
    fclose(fptr);     // don't call this is fptr is NULL. 
    remove("temp.txt");    // clean up 

    getchar();      // stop so I can see if it worked. 
} 

अपने फाइल अनुमति जाँच करने के लिए सुनिश्चित करें: अभी इस बस एक exe रूप में एक ही निर्देशिका में फाइल फेंक देते हैं। आप Vista में /tmp या Vista में C:\Users\username\Local Settings\Temp या C:\Documents and Settings\username\Local Settings\Temp in 2K/XP का उपयोग करना चाहेंगे। मुझे लगता है कि /tmp ओएसएक्स में काम करेगा, लेकिन मैंने कभी भी इसका इस्तेमाल नहीं किया है।

+0

भयानक .. :) इससे मुझे मदद मिली .. –

+0

'c' एक 'int' होना चाहिए क्योंकि' fgetc' 'int' देता है, न कि' char'। –

3

लिनक्स और ओएस एक्स में, popen() वास्तव में आपकी सबसे अच्छी शर्त है, क्योंकि डीएमकी ने बताया, क्योंकि दोनों ओएस उस कॉल का समर्थन करते हैं।Windows में, यह मदद करनी चाहिए: http://msdn.microsoft.com/en-us/library/ms682499.aspx

2

एमएसडीएन दस्तावेज यदि विंडोज प्रोग्राम में उपयोग किया जाता है, तो _popen फ़ंक्शन एक अमान्य फ़ाइल सूचक देता है जो प्रोग्राम को अनिश्चित काल तक प्रतिक्रिया देना बंद कर देता है। कंसोल एप्लिकेशन में _popen ठीक से काम करता है। विंडोज़ एप्लिकेशन बनाने के लिए जो इनपुट और आउटपुट को रीडायरेक्ट करता है, विंडोज एसडीके में रीडायरेक्ट इनपुट और आउटपुट के साथ एक चाइल्ड प्रोसेस बनाना देखें।

0
//execute external process and read exactly binary or text output 
//can read image from Zip file for example 
string run(const char* cmd){ 
    FILE* pipe = popen(cmd, "r"); 
    if (!pipe) return "ERROR"; 
    char buffer[262144]; 
    string data; 
    string result; 
    int dist=0; 
    int size; 
    //TIME_START 
    while(!feof(pipe)) { 
     size=(int)fread(buffer,1,262144, pipe); //cout<<buffer<<" size="<<size<<endl; 
     data.resize(data.size()+size); 
     memcpy(&data[dist],buffer,size); 
     dist+=size; 
    } 
    //TIME_PRINT_ 
    pclose(pipe); 
    return data; 
} 
+2

यह कौन सी भाषा है? निश्चित रूप से सी ('string.resize'?) – ugoren

+0

सी ++ की तरह दिखता है :( – gideon

1

आप के रूप system() उपयोग कर सकते हैं:

system("ls song > song.txt"); 

जहां ls फ़ोल्डर गीत की सामग्री को सूचीबद्ध करने के लिए आदेश का नाम है और song वर्तमान निर्देशिका में एक फ़ोल्डर है। परिणाम song.txt का परिणाम वर्तमान निर्देशिका में बनाया जाएगा।

+0

क्या होगा यदि मैं अन्य प्रोग्राम्स आउटपुट को फ़ाइल में रीडायरेक्ट करना चाहता हूं? ओएस कमांड –

29

जैसा कि अन्य ने इंगित किया है, popen() सबसे मानक तरीका है। और चूंकि कोई जवाब नहीं इस पद्धति का उपयोग एक उदाहरण है, यहाँ यह जाता है:

#include <stdio.h> 

#define BUFSIZE 128 

int parse_output(void) { 
    char *cmd = "ls -l";  

    char buf[BUFSIZE]; 
    FILE *fp; 

    if ((fp = popen(cmd, "r")) == NULL) { 
     printf("Error opening pipe!\n"); 
     return -1; 
    } 

    while (fgets(buf, BUFSIZE, fp) != NULL) { 
     // Do whatever you want here... 
     printf("OUTPUT: %s", buf); 
    } 

    if(pclose(fp)) { 
     printf("Command not found or exited with error status\n"); 
     return -1; 
    } 

    return 0; 
} 
+0

नहीं होना चाहिए 'अगर (pclose (fp))' ' (pclose (fp) == -1) '? –

+2

@CoolGuy: आप जो चाहते हैं उस पर निर्भर करता है। 'pclose()' return '-1' अगर कमांड की निकास स्थिति प्राप्त करने में कोई त्रुटि हुई, अन्यथा यह बाहर निकलने की स्थिति को वापस कर देता है चूंकि आदेश सफलतापूर्वक इंगित करने के लिए बाहर निकलने की स्थिति '0' सेट करते हैं,' if (pclose (fp)) की जांच करके, हम 'pclose()' या कमांड में त्रुटियों के लिए परीक्षण कर रहे हैं। – MestreLion