दिलचस्प पोस्ट
पायथन का उपयोग कर डायरेक्टरी आकार की गणना कर रहा है? जेल के अंदर पैक किया जाता है जो रन exe एक्लिप्स सीडीटी: प्रतीक 'कॉउट' का समाधान नहीं किया जा सका डिवीजन परिणाम हमेशा शून्य है xlwt का उपयोग करते हुए मौजूदा कार्यपुस्तिका को लिखना एमवीवीएम का उपयोग करते हुए एक WPF ListView आइटम से एक डबल क्लिक ईवेंट फ़ायरिंग एक MySQL ब्लॉब में संग्रहीत एक छवि प्रदर्शित करना डीएलएल लोड करने में असमर्थ (मॉड्यूल नहीं पाया जा सकता है HRESULT: 0x8007007E) कैसे पुनर्विक्रेता दृश्य के साथ एक क्षैतिज ListView बनाने के लिए? आरजीबी रंग रूपांतरण के लिए एचएसएल ओपनसीवी-पायथन में साधारण अंक मान्यता ओसीआर क्या "इनलाइन" "स्थिर" या "बाह्य" के बिना कभी भी C99 में उपयोगी है? एकाधिक एक्सटेंशन के साथ GetFiles कुछ डॉलर मूल्य दिए जाने पर सिक्कों के सभी संयोजन कैसे प्राप्त करें बैकएंड से कोणीय 2 बूटस्ट्रैप विधि को प्रदान किए गए मापदंडों को कैसे पार करें

Std :: string के साथ सी ++ printf?

मेरी समझ यह है कि string std नेमस्पेस का सदस्य है, तो निम्नलिखित क्यों होता है?

 #include <iostream> int main() { using namespace std; string myString = "Press ENTER to quit program!"; cout << "Come up and C++ me some time." << endl; printf("Follow this command: %s", myString); cin.get(); return 0; } 

यहां छवि विवरण दर्ज करें

प्रत्येक बार जब कार्यक्रम चलता रहता है, तो myString 3 वर्णों की एक यादृच्छिक स्ट्रिंग प्रिंट करता है, जैसे कि ऊपर के आउटपुट में।

वेब के समाधान से एकत्रित समाधान "Std :: string के साथ सी ++ printf?"

यह संकलन कर रहा है क्योंकि printf सुरक्षित प्रकार नहीं है, क्योंकि यह सी अर्थ 1 में चर तर्कों का उपयोग करता है। printf में std::string लिए कोई विकल्प नहीं है, केवल एक सी-शैली स्ट्रिंग है। कुछ जगहों का प्रयोग करके आप क्या चाहते हैं, इसके बारे में निश्चित रूप से आपको उम्मीद नहीं होगी। यह वास्तव में अपरिभाषित व्यवहार है, इसलिए कुछ भी हो सकता है।

इसे ठीक करने का सबसे आसान तरीका, क्योंकि आप C ++ का प्रयोग कर रहे हैं, यह सामान्यतः std::cout साथ छपाई कर रहा है, क्योंकि std::string का समर्थन करता है ऑपरेटर ओवरलोडिंग के माध्यम से:

 std::cout << "Follow this command: " << myString; 

यदि, किसी कारण के लिए, आपको सी-स्टाइल स्ट्रिंग निकालने की आवश्यकता है, तो आप एक c_str() std::string के c_str() विधि का उपयोग कर सकते हैं जो कि c_str() const char * प्राप्त करने के लिए है const char * जो कि रिक्त समाप्त है। अपने उदाहरण का उपयोग करना:

 #include <iostream> #include <string> int main() { using namespace std; string myString = "Press ENTER to quit program!"; cout << "Come up and C++ me some time." << endl; printf("Follow this command: %s", myString.c_str()); //note the use of c_str cin.get(); return 0; } 

यदि आप एक फ़ंक्शन चाहते हैं जो printf की तरह है, लेकिन सुरक्षित प्रकार, variadic टेम्पलेट्स (सी + + 11, MSVC12 के रूप में सभी प्रमुख compilers पर समर्थित) में देखें आप यहां एक का एक उदाहरण पा सकते हैं। मानक लाइब्रेरी में इस तरह लागू किए गए कुछ भी नहीं हैं, लेकिन बूस्ट में हो सकता है, विशेष रूप से boost::format


[1]: इसका मतलब है कि आप किसी भी संख्या में तर्कों को पारित कर सकते हैं, लेकिन यह कार्य आपको उन तर्कों की संख्या और प्रकारों को बताने के लिए निर्भर करता है। printf के मामले में, इसका अर्थ है एन्कोडेड प्रकार की जानकारी जैसे कि %d अर्थ int साथ एक स्ट्रिंग यदि आप प्रकार या संख्या के बारे में झूठ बोलते हैं, तो फ़ंक्शन के पास जानने का कोई मानक तरीका नहीं है, हालांकि कुछ कंपलर्स के पास जब आप झूठ बोलते हैं तो चेतावनी की जांच करने और देने की क्षमता होती है।

कृपया printf("%s", your_string.c_str()); प्रयोग न करें printf("%s", your_string.c_str());

उपयोग करें cout << your_string; बजाय। लघु, सरल और टाइपएफ़ वास्तव में, जब आप सी ++ लिख रहे हों, तो आप आम तौर पर पूरी तरह से printf से बचने के लिए चाहते हैं – यह सी से बचे हुए है जो कि सी ++ में शायद ही कभी आवश्यक या उपयोगी है

के रूप में क्यों आप printf बजाय cout उपयोग करना चाहिए, कारण कई हैं यहाँ सबसे स्पष्ट में से कुछ के नमूने हैं:

  1. जैसा कि सवाल दिखाता है, printf टाइप-सुरक्षित नहीं है यदि आप जिस प्रकार से पारित करते हैं वह रूपांतरण विनिर्देशक में दिए गए अंतर से अलग होता है, printf उस स्टैक पर जो कुछ भी मिलता है, जैसे कि यह निर्दिष्ट प्रकार था, अपरिभाषित व्यवहार प्रदान करने का प्रयास करेगा। कुछ संकलक कुछ परिस्थितियों में इस बारे में चेतावनी दे सकते हैं, लेकिन कुछ कंपलर बिल्कुल नहीं / नहीं कर सकते, और कोई भी सभी परिस्थितियों में नहीं कर सकता है।
  2. printf एक्स्टेंसिबल नहीं है आप केवल इसके लिए आदिम प्रकारों को पारित कर सकते हैं रूपांतरण विनिर्देशों का सेट यह समझता है कि इसके कार्यान्वयन में कड़ी मेहनत की जाती है, और आपके और अधिक / दूसरों को जोड़ने के लिए कोई रास्ता नहीं है सबसे अच्छी तरह से लिखित सी ++ इन प्रकारों को मुख्य रूप से समस्या का हल करने के लिए उन्मुख प्रकार लागू करने के लिए उपयोग करना चाहिए।
  3. यह सभ्य प्रारूपण को और अधिक कठिन बना देता है एक स्पष्ट उदाहरण के लिए, जब आप लोगों को पढ़ने के लिए संख्या छपाई कर रहे हैं, तो आप आमतौर पर हर कुछ अंकों के हजारों विभाजक सम्मिलित करना चाहते हैं। cout रूप में इस्तेमाल किये जाने वाले अंकों और वर्णों की सटीक संख्या भिन्न होती है, लेकिन cout में भी कवर किया गया है। उदाहरण के लिए:

     std::locale loc(""); std::cout.imbue(loc); std::cout << 123456.78; 

    अज्ञात लोकेल ("") उपयोगकर्ता के कॉन्फ़िगरेशन के आधार पर एक लोकेल चुनता है। इसलिए, मेरी मशीन पर (यूएस अंग्रेज़ी के लिए कॉन्फ़िगर) यह 123,456.78 रूप में प्रिंट करता है। किसी ऐसे व्यक्ति के लिए, जिसका कंप्यूटर जर्मनी (कॉन्फ़िगर) के लिए कॉन्फ़िगर किया गया है, वह 123.456,78 तरह कुछ प्रिंट करेगा। भारत के लिए कॉन्फ़िगर किए गए किसी के लिए, यह 1,23,456.78 रूप में मुद्रित होगा (और निश्चित रूप से कई अन्य हैं)। printf साथ मुझे बिल्कुल एक परिणाम मिलता है: 123456.78 यह संगत है, लेकिन यह हर जगह हर जगह के लिए लगातार गलत है। इसके आस-पास काम करने के लिए मूल रूप से एकमात्र तरीका स्वरूपण को अलग से करना है, फिर परिणाम को printf लिए स्ट्रिंग के रूप में देना है, क्योंकि printf स्वतः ही काम को सही ढंग से नहीं करेगा।

  4. हालांकि वे काफी कॉम्पैक्ट हैं, printf प्रारूप स्ट्रिंग काफी अपठनीय हो सकते हैं। यहां तक ​​कि सी प्रोग्रामर्स में जो हर दिन printf इस्तेमाल करते हैं, मुझे लगता है कि कम से कम 99% चीजों को ध्यान में रखना चाहिए कि # में %#x मतलब क्या है, और यह कि किस तरह से # %#f माध्यम से इसका मतलब है (और हाँ, वे पूरी तरह से अलग चीजों का मतलब है)।

myString.c_str () का उपयोग करें यदि आप printf के साथ उपयोग करने के लिए c-like स्ट्रिंग (const char *) चाहते हैं

मुख्य कारण शायद यह है कि सी ++ स्ट्रिंग एक स्ट्रेट है जिसमें एक वर्तमान-लंबाई मान शामिल है, न कि केवल 0 बाइट द्वारा समाप्त किए गए वर्णों के क्रम का पता। Printf और उसके रिश्तेदार इस तरह के एक अनुक्रम की खोज करते हैं, एक संरचना नहीं, और इसलिए सी ++ स्ट्रिंग्स द्वारा भ्रमित हो जाते हैं।

अपने लिए बोलते हुए, मेरा मानना ​​है कि printf के पास एक जगह है जो आसानी से सी ++ वाक्यविन्यास सुविधाओं से भर नहीं सकते हैं, जैसे कि html में तालिका संरचनाएं ऐसी जगह होती हैं जो आसानी से डिविज़ से भर नहीं सकते हैं जैसा कि डाइकास्ट्रा ने गोटो के बारे में बाद में लिखा था, वह एक धर्म शुरू करने का इरादा नहीं था और वास्तव में केवल खराब डिजाइन किए कोड के लिए बनाने के लिए इसे इस्तेमाल करने के खिलाफ बहस का ही तर्क था।

यह काफी अच्छा होगा यदि जीएनयू प्रोजेक्ट प्रिंटफ़ परिवार को उनके जी ++ एक्सटेंशन में जोड़ देगा

Printf वास्तव में उपयोग करने के लिए बहुत अच्छा है अगर आकार मायने रखता है जिसका मतलब है कि यदि आप एक प्रोग्राम चला रहे हैं जहां मेमोरी एक मुद्दा है, तो printf वास्तव में एक बहुत अच्छा और राटर समाधान के तहत है Cout मूल रूप से स्ट्रिंग के लिए जगह बनाने के लिए बिट्स को बदलता है, जबकि printf में केवल कुछ प्रकार के मानदंड होते हैं और स्क्रीन पर प्रिंट करता है। यदि आप एक सरल हैलो वर्ल्ड प्रोग्राम संकलित करने के लिए थे, तो printf 60% से कम बिट्स में इसे कॉट करने के लिए कम से कम संकलित करने में सक्षम होगा, इसे संकलित करने के लिए 10 लाख से अधिक बिट्स लेना होगा।

आपकी स्थिति के लिए, आईडी cout का उपयोग करने का सुझाव है क्योंकि यह उपयोग करने में अधिक सुविधाजनक है यद्यपि, मैं तर्क देता हूं कि printf कुछ अच्छी जानना है

Std :: printf और c_str () उदाहरण का प्रयोग करें:

 std::printf("Follow this command: %s", myString.c_str()); 

printf तर्कों की एक चर संख्या को स्वीकार करता है। उन में केवल सादा पुराना डेटा (पीओडी) प्रकार हो सकते हैं। संहिता जो पीओडी को छोड़कर कुछ भी printf करता है, केवल संकलित करता है क्योंकि कंपाइलर मानता है कि आपको अपना प्रारूप सही मिल गया है। %s मतलब है कि संबंधित तर्क को char लिए एक संकेतक माना जाता है। आपके मामले में यह एक std::string नहीं const char*printf इसे नहीं जानता क्योंकि तर्क प्रकार खो जाता है और स्वरूप पैरामीटर से बहाल होना चाहिए। जब उस std::string तर्क को const char* में बदलते हुए परिणामस्वरूप सूचक आपके वांछित सी स्ट्रिंग के बजाय स्मृति के कुछ अप्रासंगिक क्षेत्र को इंगित करेगा। इस कारण के लिए आपका कोड बेजान हो जाता है

जबकि printf स्वरूपित पाठ को छपाई के लिए एक उत्कृष्ट पसंद है , (खासकर यदि आप पैडिंग करना चाहते हैं), यदि आप कम्पाइलर चेतावनियों को सक्षम नहीं करते हैं, तो यह खतरनाक हो सकता है हमेशा चेतावनियां सक्षम करें क्योंकि इस तरह की गलतियों को आसानी से टाल सकते हैं। यदि कोई भी तेजी से और सुंदर तरीके से एक ही काम कर सकता है, तो फूहड़ std::cout तंत्र का उपयोग करने का कोई कारण नहीं है। बस सुनिश्चित कर लें कि आपने सभी चेतावनियां सक्षम की हैं ( -Wall -Wextra ) और आप अच्छे होंगे यदि आप अपने स्वयं के कस्टम printf कार्यान्वयन का उपयोग करते हैं, तो आपको इसे __attribute__ तंत्र के साथ घोषित करना चाहिए, जो कि कंपाइलर को प्रदान किए गए मानदंडों के खिलाफ प्रारूप स्ट्रिंग की जांच करने में सक्षम बनाता है ।