सी ++ स्प्रिंटफ के बराबर?


जवाबों:


69

std::ostringstream

उदाहरण:

#include <iostream>
#include <sstream> // for ostringstream
#include <string>

int main()
{
  std::string name = "nemo";
  int age = 1000;
  std::ostringstream out;  
  out << "name: " << name << ", age: " << age;
  std::cout << out.str() << '\n';
  return 0;
}

आउटपुट:

name: nemo, age: 1000

3
मुझे नहीं लगता कि स्प्रिंटफ स्टडआउट को लिखता है। मैं ऊपर का सम्मिलन विवरण निकालूंगा।
रफ़ी खाचदौरेन

81
यह कैसे दूर से भी समान है sprintf (...)? आप डेटा को मनमाने ढंग से प्रारूपित नहीं कर सकते, आपको उस प्रकार पर भरोसा करना होगा जब आप इसे <<ऑपरेटर के उपयोग से स्ट्रीम में फीड करते हैं ।
एंडॉन एम। कोलमैन

1
मुझे इस बारे में @ AndonM.Coleman से सहमत होना होगा। यह वास्तव में स्प्रिंटफ प्रतिस्थापन नहीं है। यह इस तरह अधिक होगा, लेकिन यह क्यूटी है।
lpapp

जैसा कि @vinkris अपने जवाब में कहता है, iomanip स्वरूपण प्राप्त करता है। स्टोंडिट को प्रिंट करने के बजाय, मैं "परिणाम = आउट.स्ट्रस्ट ()" कहूंगा।
दिमित्री

sprintf / snprintf उपयोगकर्ता को आवंटित चरित्र सरणी के निर्माण और मुद्रण की अनुमति देता है, स्टैक पर हो सकता है। स्निप्रफ () के मामले में, यह सुनिश्चित करता है कि कोई अतिरंजना न हो। यहां हम कई बार मेमोरी आवंटित कर रहे हैं और कॉल करने वाले की सीधी पहुंच नहीं है। आउटपुट प्राप्त करने के लिए एक स्ट्रिंग में बदलना होगा। एक std :: कस्टम std :: streambuf, जो उपयोगकर्ता बफर लेता है, के साथ एक बेहतर मैच होगा - बेशक निर्माण / ostream / streambuf का विनाश अधिक दक्षता में जोड़ता है।
एमजीएच

35

अपडेट, अगस्त 2019:

ऐसा लगता है कि C ++ 20 होगा std::format। संदर्भ कार्यान्वयन {fmt} है । यदि आप printf()अभी एक विकल्प की तलाश कर रहे हैं, तो यह नया "मानक" दृष्टिकोण बन जाएगा और विचार करने योग्य है।

मूल:

Boost.Format का उपयोग करें । इसमें समान printf-प्रकार के सिंटैक्स, प्रकार की सुरक्षा, std::stringपरिणाम और बहुत सारे अन्य निफ्टी सामान हैं। तुम वापस नहीं जाओगे।


15
... जब तक आप अपने निष्पादन योग्य के आकार के बारे में चिंतित नहीं हैं ..: P
pradyunsg

इसका कितना असर होगा? बूस्ट निर्भरता केवल हेडर होगी, कोई लिंकिंग नहीं, सही?
केन विलियम्स

1
@KenWilliams हाँ, Boost.Format केवल हेडर है। मेरे मैक पर एक साधारण "हैलो, वर्ल्ड" टेस्ट 10kB से 78kB तक बढ़ जाता है। एक वास्तविक परियोजना में अतिरिक्त आकार को संकलन इकाइयों (सही लिंकर विकल्प दें) में परिशोधन किया जाएगा, और प्रकार की सुरक्षा अन्य लाभ लाती है।
janm

18

स्प्रिंटफ C ++ में ठीक काम करता है।


5
मुझे लगता है कि C ++ के बजाय OP का मतलब STL था।
जीन-मिकेल सेलेरियर

4
स्प्रिंटफ आपको चरित्र बफर आवंटित करने की आवश्यकता है। मैं "std :: string" के "परिशिष्ट" पद्धति की तरह कुछ करना चाहूंगा जो मुझे स्वरूपित डेटा जोड़ने की अनुमति देता है, और पर्दे के पीछे आवंटित करने का ख्याल रखता है।
विक्टर आइजखौट

7

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


किसी ने इसे कम क्यों किया? क्या आयतों को शुद्ध-सी ++ धाराओं में प्रारूपण प्राप्त करने का तरीका नहीं है? मुझे लगता है कि यहां लक्ष्य सी-स्टाइल स्ट्रिंग्स में डेटा संग्रहीत करने से बचना है, जो कि iomanip के साथ हासिल किया गया है।
दिमित्री

7

यहां सी ++ स्प्रिंटफ के लिए एक अच्छा कार्य है। यदि आप उन्हें बहुत अधिक उपयोग करते हैं तो धाराएँ बदसूरत हो सकती हैं।

std::string string_format(const std::string &fmt, ...) {
    int size=100;
    std::string str;
    va_list ap;

    while (1) {
        str.resize(size);
        va_start(ap, fmt);
        int n = vsnprintf(&str[0], size, fmt.c_str(), ap);
        va_end(ap);
   
        if (n > -1 && n < size) {
            str.resize(n); // Make sure there are no trailing zero char
            return str;
        }
        if (n > -1)
            size = n + 1;
        else
            size *= 2;
    }
}

C ++ 11 और बाद में, std :: string को सन्निहित भंडारण का उपयोग करने की गारंटी दी जाती है '\0', जो कि समाप्त होती है , इसलिए इसे char *उपयोग करने के लिए डालना कानूनी है &str[0]

यह बताया गया है कि वैरिएड तर्कों को पास-बाय-रेफरेंस का पालन नहीं किया जाता है, और c ++ स्ट्रिंग्स की नकल न करने के बारे में अच्छा है यदि इसे नहीं करना है। उस स्थिति में, यह इसे ठीक करता है।

std::string string_format(std::string fmt, ...) {

बहुत अच्छा समाधान! मैंने इसे यहाँ अनुकूलित किया है: stackoverflow.com/a/3742999/15161 से अधिक बारीकी से फिट होने के लिए sprintf
स्लैशमाईस 18

10
हालांकि, अवैध: (char*) str.c_str()दूर const
MSalters

यहां तक ​​कि बफर ओवरफ्लो समस्या भी है
बार्नी ज़ाबोलक्स

@MSalters सही। C ++ 11 में ऐसा करने का कानूनी तरीका है।
श्वेतार्क

@whitequark: एक उत्तर के रूप में जोड़ने के लिए स्वतंत्र महसूस करें। स्टैक ओवरफ्लो पर, नए प्रश्नों की अनुमति देने के लिए अच्छा प्रश्न खुला रहता है।
MSalters

1

क्या आप वास्तव में sprintf()आईएनजी पर योजना के आधार पर std::to_string()अन्य विकल्पों की तुलना में उपयोगी और अधिक मुहावरेदार हो सकते हैं:

void say(const std::string& message) {
 // ...
}

int main() {
  say(std::to_string(5));
  say("Which is to say " + std::to_string(5) + " words");
}

std::to_string()IMHO का मुख्य लाभ यह है कि इसे अतिरिक्त प्रकारों का समर्थन करने के लिए आसानी से बढ़ाया जा सकता है, जो sprintf()स्ट्रिंग के प्रकार का सपना भी नहीं देख सकता है - जैसे जावा की Object.toString()विधि।


0

उसी प्रभाव को प्राप्त करने के लिए एक स्ट्रीस्टस्ट का उपयोग करें। इसके अलावा, आप शामिल कर सकते हैं <cstdio>और अभी भी स्निपरफ का उपयोग कर सकते हैं ।

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