2011-05-24 25 views
6

मेरे पास abc नामक प्रोग्राम है।stdout रीडायरेक्ट आउटपुट को रीडायरेक्ट रीडायरेक्ट

जब मैं निम्नलिखित कमांड चलाएँ:

$ ./abc < infile 

मैं निम्नलिखित उत्पादन प्राप्त करें:

ijklm 

हालांकि, जब मैं चलाएँ:

$ ./abc <infile> outfile 
$ cat outfile 

मैं इस उत्पादन को देखते हुए कर रहा हूँ:

ijkoo 

अब, मुझे लगता है कि यह मेरे कार्यक्रम के साथ एक बग है। हालांकि, मेरा कार्यक्रम क्या कर रहा है इस पर ध्यान दिए बिना, मुझे नहीं पता कि यह कैसे संभव है।

संपादित करें:

अब मुझे पता है कि यह संभव है, मैं क्या यह मेरे कार्यक्रम जाता है कि इस कारण है के रूप में उत्सुक हूँ।

byte = ascii_to_byte(asciibyte); 
putchar(byte); 

बाइट प्रकार char की है:

मेरे कार्यक्रम में एक पाश है कि होता है अंदर एक ब्लॉक है।

अब अगर मैं putchar(byte) से printf("%c", byte) बदलता हूं तो सभी आउटपुट वही रहता है।

हालांकि, अगर मैं इसे printf("%d", byte) को बदलने के लिए, तो $ ./abc < infile आउटपुट:

105106107111111 

कौन उन ASCII वर्ण दशमलव प्रतिनिधित्व के रूप में वे outfile में थे। लेकिन यह वर्णों का दशमलव प्रतिनिधित्व नहीं है क्योंकि वे वास्तव में तब दिखाई दिए जब वे अभी stdout पर भेजे गए थे। मुझे समझ में नहीं आता कि यह अंतर क्यों हो सकता है।

संपादित करें # 2:

अगर मैं printf("%c\n", byte) को मुद्रण लाइन बदलने के लिए, तो $ ./abc < infile आउटपुट:

i 
j 
k 
o 
o 

यह वही है outfile में चला जाता है के अनुरूप है। फिर, सुनिश्चित नहीं है कि अंतर क्या है।

संपादित # 3

मैं सिर्फ एक 32 बिट मशीन पर यह परीक्षण किया है, और इस कार्यक्रम काम करता है: outputfileijklm शामिल हैं। अजीब।

संपादित करें # 4

यहाँ मुख्य कार्य है: यहाँ

int main() 
{ 
    char asciibyte[8]; 
    char byte; 

    int c; //Using int to avoid the EOF pitfall. 
    long charcount = 0; 

    while((c = getchar()) != EOF){ 
     if(c != '0' && c != '1'){ 
      continue; 
     } 
     asciibyte[charcount % 8] = c; 
     if(charcount % 8 == 7){ 
      /*Testing revealed that at this point asciibyte does contain 
      what it should contain, eight ASCII ones and zeros representing 
      a byte read in from stdin*/ 
      byte = ascii_to_byte(asciibyte); 
      /*Print statements such as: 
       printf("%d", byte); 
       printf("%c\n", byte); 
      reveal that the ascii_to_byte function works incorrectly on my 
      64 bit machine. However these statements: 
       putchar(byte); 
       printf("%c", byte); 
      make it appear as though the function operates as it should. 
      EXCEPT if i redirect that output to a file.*/ 
      putchar(byte); 
     } 
     charcount++; 
    } 
    return 0; 
} 

और ascii_to_byte समारोह है:

char ascii_to_byte(char *asciibyte){ 
    char byte; 
    int i; 
    for(i = 0; i < 8; ++i){ 
     if(asciibyte[7-i] == '1'){ 
      byte = byte | (1 << i); 
     } 
    } 
    return byte; 
} 

अंतिम संपादन

मैंने देखा कि मुझे बाइट को 0x00 में प्रारंभ करना चाहिए था। समस्या सुलझ गयी। मैं इसे क्यों मंद कर रहा हूँ? मैं उत्तरदायी बिंदु दूंगा जो भी विशेष रूप से समझा सकता है कि इससे समस्या कैसे हुई।

+0

आउटपुट हमेशा एक ही है? यदि आप दो बार /abc चलाते हैं, तो क्या आपको वही परिणाम मिलता है? –

+0

हां, आउटपुट कई परीक्षणों पर संगत है। – oadams

+0

'./abc pmg

उत्तर

1

यह निश्चित रूप से संभव है - कार्यक्रम यह जांच सकता है कि क्या यह टर्मिनल पर लिख रहा है और पाइप पर लिखते समय लिखने से कुछ अलग लिखता है।

0

क्या नील बटरवर्थ कहते हैं। फ़ंक्शन को isatty कहा जाता है।

if (isatty(STDOUT)) printf("I am printing to the terminal!\n"); 

इसके अलावा, जबकि परीक्षण सामान, तुमने क्या किया हो सकता है:

$ ./abc <infile> infile 

दुर्घटना से। तो, आप जल्दी से जांचना चाहेंगे, infile में वास्तव में एक ही डेटा है।

+0

हाँ मैंने इसे विभिन्न परीक्षण इनपुट के साथ कई बार किया है, और मैं अभी भी डरावना हूं। – oadams

3

इस प्रकार का अजीब व्यवहार, जो प्रतीत होता है कि असंबद्ध परिवर्तनों के अनुसार आता है और जाता है, शायद आपके प्रोग्राम को पढ़ने या स्मृति में लिखने का संकेत है, और कोड के अन्य हिस्सों के रूप में बदलते व्यवहार का अलग-अलग उपयोग होता है ढेर और/या ढेर के।

मैं ऐसे बफर लगने, कार्य करता है जो ढेर पर चर की ओर इशारा वापसी, आदि

एक डिबगर के साथ अपने कोड के माध्यम से कदम अच्छी तरह से (या इसे बदल सकता है उत्पादक हो सकता है के रूप में बुराई के लिए ध्यान से अपने कोड की जाँच करेगा यदि आप दुर्भाग्यपूर्ण हैं तो फिर से व्यवहार करें!)।

  1. कैसे stdout की पुनर्निर्देशन संभवतः कुछ भी प्रभावित कर सकते हैं:

    आप देखा है दिलचस्प बातें की एक जोड़ी रहे हैं? शायद क्योंकि यह सी लाइब्रेरी को थोड़ा अलग तरीके से व्यवहार करने का कारण बनता है: स्ट्रीम के लिए एक अलग बफरिंग मोड का उपयोग किया जाता है, इस पर निर्भर करता है कि यह किसी टर्मिनल डिवाइस से कनेक्ट है या नहीं (GNU libc documentation, या C99 §7.9.13 पैरा देखें। 7) ।

  2. क्यों बदल रहा printf("%c", byte) को putchar(byte) कुछ भी नहीं बदलता है, जब दोनों printf("%d", byte) और printf("%c\n", byte) व्यवहार बदल सकता हूँ? शायद क्योंकि संकलक स्वचालित रूप से printf("%c", byte) को अधिक कुशल putchar(byte) पर फिर से लिखता है - जीसीसी के अस्पष्ट हाल के संस्करण सामान्य रूप से ऐसा करते हैं, भले ही कोई ऑप्टिमाइज़ेशन सक्षम न हो - जबकि printf("%d", byte) और printf("%c\n", byte) वास्तव में printf() पर कॉल के रूप में संकलित किए जाएंगे।

1

आप कहते हैं के रूप में, byte तो कुछ भी हो सकता है अप्रारंभीकृत है।

कुछ चीजें जो हो सकती हैं, यह है कि byte 0 पर "शुरू होता है" और फ़ंक्शन कॉल से फ़ंक्शन कॉल तक अपना मान रखता है (जैसे कि इसे static घोषित किया गया था)।

 
in binary ... 

    byte | c (bin) | byte | c 
-----------+--------------+-------------- 
00000000 | i (01101001) | 01101001 (i) 
01101001 | j (01101010) | 01101011 (k) * strange you get 'j', but anything can happen :) 
01101011 | k (01101011) | 01101011 (k) 
01101011 | l (01101100) | 01101111 (o) 
01101111 | m (01101101) | 01101111 (o) 
संबंधित मुद्दे