मुझे पेरोर ("...") और फ़र्प्रिंट (स्टडर, "...") का उपयोग कब करना चाहिए?


105

मैन पेज और कुछ कोड को पढ़ने से मुझे वास्तव में - या बेहतर के बीच के अंतर को समझने में मदद नहीं मिली, जब मुझे उपयोग करना चाहिए - perror("...")या fprintf(stderr, "...")

जवाबों:


113

कॉल करने perrorसे आपको इसका errnoअनुमानित मूल्य मिलेगा, जो कि POSIX syscalls द्वारा लिखित थ्रेड-लोकल एरर वैल्यू है (यानी, हर थ्रेड का अपना मान है errno)। उदाहरण के लिए, यदि आपने कॉल किया था open(), और कोई त्रुटि उत्पन्न हुई (यानी, यह वापस आ गई -1), तो आप perrorतुरंत कॉल कर सकते हैं कि वास्तविक त्रुटि क्या है। ध्यान रखें कि यदि आप इस बीच अन्य syscalls को कॉल करते हैं, तो मूल्य में errnoलिखा जाएगा, और कॉल करने perrorसे आपके समस्या का निदान करने में कोई फायदा नहीं होगा यदि कोई त्रुटि पहले syscall द्वारा उत्पन्न की गई थी।

fprintf(stderr, ...)दूसरे हाथ पर अपने स्वयं के कस्टम त्रुटि संदेश मुद्रित करने के लिए इस्तेमाल किया जा सकता है। प्रिंट करने से stderr, आप "सामान्य" आउटपुट के साथ मिश्रित होने वाले अपने त्रुटि रिपोर्टिंग आउटपुट से बचते हैं जो कि होना चाहिए stdout

ध्यान रखें कि रखें fprintf(stderr, "%s\n", strerror(errno))के समान है perror(NULL)एक फोन के बाद से strerror(errno)के लिए मुद्रित स्ट्रिंग मान उत्पन्न होगा errno, और आप तो है कि किसी भी अन्य कस्टम त्रुटि संदेश के साथ के माध्यम से संयुक्त कर सकते हैं fprintf


3
ओह, समझ में आ गया। पेरोन फ़ंक्शन गलत तरीके से काम करता है। If you use a function that effects errno then it makes sense to use perror। यदि आप एक फ़ंक्शन का उपयोग करते हैं जो कि गलत प्रभाव नहीं डालता है और बस एक त्रुटि कोड देता है तो आपको fprintf (stderr, fmt, ...) का उपयोग करना चाहिए। उदाहरण के लिए, अगर स्ट्रिंग एक सीमा से बाहर है और इरेंज में इरानो को सेट कर देता है, तो स्ट्रेटोल LONG_MAX या LONG_MIN लौटाएगा। इसलिए यदि स्ट्रेटोल सीमा से बाहर होने के कारण विफल हो जाता है, तो मैं पेरार का उपयोग करूंगा।
freeboy1015

6
एक विस्तार, strerrorधागा-सुरक्षित होने की आवश्यकता नहीं है। यह बेवकूफी है, लेकिन यह मानक है। strerror_lPOSIX 2008 सिस्टम पर ड्रॉप-इन प्रतिस्थापन के रूप में उपयोग किया जा सकता है। strerror_rपुराने सिस्टम पर भी उपलब्ध है, लेकिन वास्तव में इसके कुछ संस्करणों के साथ गैर-अनुरूपण वाले मुद्दों के साथ बुरा मुद्दा है।
आर .. गिटहब स्टॉप हेल्पिंग ICE

एक नाइटपिक के रूप में भी, मुझे लगता है कि अंत में perrorजोड़ता है '\n'इसलिए प्रारूप होगा "%s\n"?
जेन्स गुस्तेद

1
@ आर .., हा, मेरे पास पहले से ही है, और जहाँ तक मुझे पता है कि वे मुझे एक चीज़ नहीं दे रहे हैं। और जब से लगता है कि एमएस पूरी तरह से सी के लिए अपने समर्थन में कटौती कर रहा है, अंत में मैं केवल एक ही होऊंगा :) strerror_sवास्तव में एक इंटरफ़ेस के रूप में बहुत बुरा नहीं है।
जेन्स गुस्टेड

2
काटने का समर्थन पूरी तरह से? लगता है कि उन्होंने समिति को फिर से बेवकूफ बनाया। _sमानक में उनके कबाड़ को प्राप्त करना मूल रूप से एमएस द्वारा एक खेल था ("यदि आप हमारे इंटरफेस को अपनाते हैं, तो हम वास्तव में हमारे मानक का समर्थन करने पर विचार करेंगे") और निश्चित रूप से अब वे इसका पालन नहीं कर रहे हैं। वास्तव में मैं मानता हूं कि यह एक इंटरफ़ेस अपने आप में बुरा नहीं है। क्या बुरा है प्रचार (संकलक चेतावनियों के रूप में) कि अधिकांश मानक पुस्तकालय "असुरक्षित" है और _sमानक के बजाय कार्यों के पूरे परिवार का उपयोग किया जाना चाहिए।
R .. गिटहब स्टॉप हेल्पिंग ICE

40

वे अलग-अलग चीजें करते हैं।

आप उस perror()संदेश को प्रिंट करने के लिए उपयोग करते हैं stderrजो इससे मेल खाता है errno। आप किसी भी चीज़ को या किसी अन्य स्ट्रीम fprintf()को प्रिंट करने के लिए उपयोग करते हैं । एक विशेष मुद्रण कार्य है:stderrperror()

perror(str);

के बराबर है

if (str)
    fprintf(stderr, "%s: %s\n", str, strerror(errno));
else
    fprintf(stderr, "%s\n", strerror(errno));

12

perror(const char *s): आपके द्वारा दी जाने वाली स्ट्रिंग को एक स्ट्रिंग द्वारा प्रिंट करता है जो वर्तमान मूल्य का वर्णन करता है errno

stderr: यह एक आउटपुट स्ट्रीम है जो आपके स्वयं के एरर मैसेजेस को टर्मिनल में डिफॉल्ट करने के लिए उपयोग किया जाता है।

से मिलता जुलता:

char *strerror(int errnum): इसे एक त्रुटि संख्या दें, और यह संबंधित त्रुटि स्ट्रिंग लौटा देगा।


2

perror () हमेशा stderr को लिखता है; ferrf () के साथ एक साथ उपयोग किए जाने वाले स्ट्रेर (), किसी भी आउटपुट को लिख सकते हैं - जिसमें स्टेडर भी शामिल है, लेकिन विशेष रूप से नहीं।

fprintf(stdout, "Error: %s", strerror(errno));
fprintf(stderr, "Error: %s", strerror(errno)); // which is equivalent to perror("Error")

इसके अलावा, पेरोर "टेक्स्ट: एरर डिस्क्रिप्शन" के रूप में अपना स्वयं का पाठ लगाता है


-2

पेरियर फंक्शन को निष्पादन करने में अधिक समय लगता है, उपयोगकर्ता स्पेस से कर्नेल स्पेस में जाता है, फ़र्स्टफ़ फ़ाइर्फ़ कॉल गोस्ट टू एपी से कर्नेल

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.