2012-06-14 8 views
14

पर stdout को पुनर्स्थापित करें मैं एक बहु-थ्रेड प्रोग्राम के साथ काम कर रहा हूं।सी टर्मिनल

सबसे पहले मैं अपने stdout को एक निश्चित फ़ाइल पर रीडायरेक्ट करता हूं। वहां कोई समस्या नहीं है (मैंने dup2(fd, 1) का उपयोग किया जहां fd फ़ाइल के लिए फाइल डिस्क्रिप्टर है)।

बाद में, मुझे अपने stdout को फिर से टर्मिनल पर रीडायरेक्ट करने की आवश्यकता है।

मेरा पहला दृष्टिकोण:

 /*Declaration*/ 
     fpost_t stream_sdout; 
     /*code*/ 
     if (fgetpos(stdout, &stream_sdout) == -1) 
      perror(Error:); 

यह अवैध कहते हैं चाहते हैं।
कोई विचार नहीं कि यह क्यों हो रहा है।
लेकिन अगर मुझे यह काम करने के लिए मिलता है, तो मुझे केवल fsetpos(stdout, &stream_stdout) का उपयोग करने की आवश्यकता है और इसे काम करना चाहिए।

मेरा दूसरा विचार, स्थिति वर्णन 4 पर dup2(stdout, 4) फ़ाइल डिस्क्रिप्टर तालिका में stdout की प्रतिलिपि बनाना था, लेकिन यह या तो काम नहीं कर रहा है।

मैं मानक आउटपुट को अपने मूल गंतव्य (टर्मिनल, पाइप, फ़ाइल, जो कुछ भी) पर वापस कैसे स्विच कर सकता हूं?

+0

मुझे एहसास है कि इस तरह के आसपास 'stdout' को स्थानांतरित करने का प्रयास करना शायद एक बुरा विचार है - _ fgetpos()' में _terminal_ रिपोर्ट को वास्तव में क्या स्थिति चाहिए? 'Fwrite() 'या' fprintf()' या 'write() 'और टर्मिनल पर आउटपुट को'/dev/tty' के माध्यम से आउटपुट के जरिए इसे फ़ाइल और आउटपुट क्यों खोलें? – sarnold

+1

@ कर्नाल्ड: शायद क्योंकि प्रोग्राम में पुस्तकालय या अन्य अस्थिर कोड हैं जो 'stdout' के लिए कड़ी मेहनत कर रहे हैं। – wallyk

+0

@ कर्नाल्ड मैंने वास्तव में इसे उस सकारात्मकता के बारे में सोचा नहीं था। मुझे जल्दी से जांचने दो। – Alessandroempire

उत्तर

21
#include <unistd.h> 

... 

int saved_stdout; 

... 

/* Save current stdout for use later */ 
saved_stdout = dup(1); 
dup2(my_temporary_stdout_fd, 1); 

... do some work on your new stdout ... 

/* Restore stdout */ 
dup2(saved_stdout, 1); 
close(saved_stdout); 
+2

क्या आप टाइप किए गए मेरे कंधे पर पढ़ रहे थे? –

+0

यह वास्तव में मुझे बहुत मदद की। मैं सोच रहा था कि करीब (save_stdout) का कार्य क्या है? मैंने फ़ाइलों को बंद करने के लिए बंद किया है, लेकिन मैं अभी तक परिचित नहीं हूं कि पूरी डुप्ली फ़ंक्शन प्रक्रिया कैसे काम करती है। – ThinkBonobo

+1

@TinkBonobo, 'saved_stdout' प्रोग्राम के stdout के अंतर्गत मूल फ़ाइल के लिए मूल फ़ाइल वर्णनकर्ता का डुप्लिकेट (इसलिए, * dup() *) है। इसे फिर से डुप्लिकेट किया जाता है (* dup2() *) stdout (फ़ाइल डिस्क्रिप्टर संख्या 1), प्रोग्राम में एक ही अंतर्निहित फ़ाइल के लिए दो प्रतियां/हैंडल/वर्णनकर्ता हैं। एक बार आउटपुट रीडायरेक्शन समाप्त हो जाने के बाद इसकी आवश्यकता नहीं है (और यह संसाधन सीमा या फाइल लॉक आदि के बारे में धारणाओं को भंग कर सकता है), इसलिए अब अभ्यास की आवश्यकता नहीं होने पर संसाधन को खारिज करना अच्छा अभ्यास है। STDOUT_FILENO के लिए – pilcrow

0

यदि प्रोग्राम लिनक्स पर्यावरण पर चलता है, तो आप freopen ("/dev/stdout", "a", stdout) कर सकते हैं।

लेकिन क्या आप जानते है कि stdout टर्मिनल, freopen ("/dev/tty", "a", stdout) या अन्य OS — भी विंडोज के लिए बराबर था।

+1

जब 'dup2()' काम करता है, '/ dev/stdout' फ़ाइल को संदर्भित करना चाहिए। इसलिए आपने फ़ाइल से आउटपुट को फ़ाइल में स्विच कर दिया है, मुझे विश्वास है। –

+0

@ जोनाथन लेफ्लर: यदि वह 'एफडी' को बदल रहा है, तो यह सच होगा। यह उनके वर्णन से स्पष्ट है कि क्या हो रहा है। ऐसा लगता है कि वह इसके बजाय FILE कनेक्शन के आसपास बदल सकता है। – wallyk

+0

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

6

इससे पहले कि आप dup2(fd, STDOUT_FILENO) करते हैं, आप कर int saved_stdout = dup(STDOUT_FILENO); (दे dup() आप के लिए एक उपलब्ध फ़ाइल वर्णनकर्ता संख्या चुन) द्वारा मानक उत्पादन के लिए मौजूदा फ़ाइल खोलने वर्णनकर्ता को बचाने चाहिए। फिर, जब आप किसी फ़ाइल पर रीडायरेक्ट किए गए आउटपुट के साथ समाप्त कर लेंगे, तो आप मानक आउटपुट को पुनर्स्थापित करने के लिए dup2(saved_stdout, STDOUT_FILENO) कर सकते हैं जहां यह सब शुरू करने से पहले था (और आपको saved_stdout भी बंद करना चाहिए)।

आपको उचित समय पर मानक I/O धाराओं (fflush(stdout)) को फ़्लश करने की चिंता करने की आवश्यकता है क्योंकि आप इसके साथ गड़बड़ करते हैं। इसका मतलब है 'इससे ​​पहले कि आप स्टडआउट स्विच करें'।

+3

+1 यह इसे बहुत अधिक पठनीय बनाता है। –