वास्तव में स्ट्रिंगस्ट्रीम क्या करता है?


107

मैं कल से C ++ सीखने की कोशिश कर रहा हूं और मैं इस दस्तावेज का उपयोग कर रहा हूं: http://www.cplusplus.com/files/tutorial.pdf (पेज 32)। मुझे दस्तावेज़ में एक कोड मिला और मैंने उसे चलाया। मैंने कीमत के लिए 5.5 रुपये और एक पूर्णांक के लिए इनपुट की कोशिश की और आउटपुट 0. था। मैंने 5.5 और 6 का इनपुट करने की कोशिश की और आउटपुट सही था।

// stringstreams
#include <iostream> 
#include <string> 
#include <sstream> 

using namespace std; 

int main () 
{ 
  string mystr; 
  float price = 0; 
  int quantity = 0; 

  cout << "Enter price: "; 
  getline (cin,mystr); 
  stringstream(mystr) >> price; 
  cout << "Enter quantity: "; 
  getline (cin,mystr); 
  stringstream(mystr) >> quantity; 
  cout << "Total price: " << price*quantity << endl; 
  return 0; 
}

प्रश्न: वास्तव में मिस्ट्रिंग कमांड क्या करती है? दस्तावेज़ से उद्धरण:

"इस उदाहरण में, हम मानक इनपुट से अप्रत्यक्ष रूप से संख्यात्मक मान प्राप्त करते हैं। मानक इनपुट से सीधे संख्यात्मक मान निकालने के बजाय, हम मानक इनपुट (सिने) से एक स्ट्रिंग ऑब्जेक्ट (मिस्टर) में लाइनें प्राप्त करते हैं, और फिर हम पूर्णांक निकालते हैं। इस स्ट्रिंग से टाइप इंट (मात्रा) के एक चर में मान। "

मेरी धारणा यह थी कि फ़ंक्शन एक स्ट्रिंग के अभिन्न अंग को ले जाएगा और इनपुट के रूप में उपयोग करेगा।

(मैं वास्तव में यहाँ एक सवाल पूछने के लिए कैसे पता नहीं है। मैं भी प्रोग्रामिंग के लिए नया हूँ) धन्यवाद।


18
यह उदाहरण थोड़े अजीब है, मैंने कभी stringstreamइस तरह से इस्तेमाल नहीं किया है। मैं आमतौर पर, लाइन लोड परिवर्तित और फिर, भागों से निकालने लेकिन इस स्पष्ट रूप से थोड़ा लाभ यहाँ नहीं है, क्योंकि cin है एक इनपुट धारा पहले से ही ... तो cin >> price >> quantity;बहुत आसान द्वारा किया जाएगा। यह cplusplus.com ट्यूटोरियल का उपयोग नहीं करने का एक अच्छा कारण होगा ।
बार्टेक बानचेविच

6
अजीब बात है कि उस ट्यूटोरियल C ++ के लिए मेरा पहला प्रदर्शन था। अड़चन में, यह बहुत गरीब और अधूरा है। मैं इसके बजाय एक अच्छी किताब सुझाता हूँ ।
ज्रोक

@BartekBanachewicz शायद उन्हें उदाहरण के साथ आने की ज़रूरत है कि कैसे stringstreamकाम करता है। यह एक विचित्र है शायद एक भी बुरा =) लेकिन यह दर्शाता है कि आप एक धारा के रूप में स्ट्रिंग का इलाज कर सकते हैं।
luk32

यदि यह अधिक उन्नत उपयोगों का परिचय नहीं है stringstreamतो यह निश्चित रूप से एक गलत उदाहरण है। और अगर है भी तो उसे अलग तरह से लिखा जाना चाहिए।
j_kubik

1
@trojansdestroy आप उन सभी प्राथमिकताओं को समझे बिना स्ट्रिंग को समझ नहीं सकते, जो इस पर आधारित हैं, इसलिए मैं यह नहीं देखता कि ट्यूटोरियल को पढ़ने से उस संबंध में कैसे मदद मिलती है।
बार्टेक बानचेविच

जवाबों:


163

कभी-कभी स्ट्रिंग और अन्य संख्यात्मक प्रकारों के बीच परिवर्तित करने के लिए स्ट्रिंगस्ट्रीम का उपयोग करना बहुत सुविधाजनक होता है। के उपयोग के stringstreamसमान है iostream, इसलिए यह सीखने का बोझ नहीं है।

स्ट्रिंग्सस्ट्रीम का उपयोग दोनों स्ट्रिंग्स को पढ़ने और स्ट्रिंग्स में डेटा लिखने के लिए किया जा सकता है। यह मुख्य रूप से एक स्ट्रिंग बफर के साथ कार्य करता है, लेकिन एक वास्तविक I / O चैनल के बिना।

स्ट्रिंगस्ट्रीम वर्ग के मूल सदस्य कार्य हैं

  • str(), जो स्ट्रिंग प्रकार में इसके बफर की सामग्री लौटाता है।

  • str(string), जो स्ट्रिंग तर्क के लिए बफर की सामग्री को सेट करता है।

यहां स्ट्रिंग स्ट्रीम का उपयोग करने का एक उदाहरण दिया गया है।

ostringstream os;
os << "dec: " << 15 << " hex: " << std::hex << 15 << endl;
cout << os.str() << endl;

परिणाम है dec: 15 hex: f

istringstream कमोबेश यही उपयोग है।

सारांशित करने के लिए, स्ट्रिंगस्ट्रीम एक स्वतंत्र I / O डिवाइस की तरह तारों को हेरफेर करने का एक सुविधाजनक तरीका है

FYI करें, वर्गों के बीच विरासत संबंध हैं:

स्ट्रिंग स्ट्रीम कक्षाएं


19

प्रश्न का उत्तर देने के लिए। stringstreamमूल रूप से आप किसी stringवस्तु की तरह व्यवहार कर सकते हैं stream, और streamउस पर सभी कार्यों और ऑपरेटरों का उपयोग कर सकते हैं।

मैंने देखा कि यह मुख्य रूप से स्वरूपित आउटपुट / इनपुट अच्छाई के लिए उपयोग किया जाता है।

एक अच्छा उदाहरण c++वस्तु को स्ट्रीम करने के लिए संख्या को परिवर्तित करने का कार्यान्वयन होगा ।

संभावित उदाहरण:

template <class T>
string num2str(const T& num, unsigned int prec = 12) {
    string ret;
    stringstream ss;
    ios_base::fmtflags ff = ss.flags();
    ff |= ios_base::floatfield;
    ff |= ios_base::fixed;
    ss.flags(ff);
    ss.precision(prec);
    ss << num;
    ret = ss.str();
    return ret;
};

शायद यह थोड़ा जटिल है लेकिन यह काफी जटिल है। आप stringstreamऑब्जेक्ट बनाते हैं ss, उसके झंडे को संशोधित करते हैं, इसके साथ एक नंबर डालते हैं operator<<, और इसके माध्यम से निकालते हैं str()। मुझे लगता है किoperator>> इसका इस्तेमाल किया जा सकता है।

इस उदाहरण में भी stringबफर छिपा है और स्पष्ट रूप से उपयोग नहीं किया गया है। लेकिन हर संभावित पहलू और उपयोग-मामले के बारे में लिखने के लिए पोस्ट की बहुत लंबी अवधि होगी।

नोट: मैंने शायद इसे SO और रिफाइंड पर किसी से चुराया था, लेकिन मेरे पास मूल लेखक नहीं है।


3
नोट: का उपयोग retअनावश्यक है, एक लिख सकता है return ss.str();
मैथ्यू एम।

@MatthieuM। मुझे लगता है कि मुझे यकीन नहीं था कि अगर RVO किक-इन होता है, तो ऐसा ही लिखा जाता है, या यदि ऑब्जेक्ट ss.str द्वारा वापस आ जाता है (तो) निकास बिंदु से बच जाएगा। इस तरह मुझे पता है कि मैं एक कॉपी बना रहा हूं, और आरवीओ काम करेगा। लेकिन आप शायद सबसे सही हैं।
luk32

वास्तव में, आरवीओ के 2 रूप हैं: यूआरवीओ (अनाम के लिए, वह अस्थायी है) और एनआरवीओ (नाम के लिए); अधिकांश संकलक आरवीओ को लागू करते हैं, लेकिन कुछ इसे केवल यूआरवीओ (बिल्ड विकल्पों के आधार पर) तक सीमित रखते हैं। सामान्य तौर पर, हालांकि, खाते में लेने के लिए बहुत सारे अन्य कारक हैं, इसलिए आपको बस सबसे साफ कोड लिखना चाहिए और इस बारे में बहुत अधिक चिंता नहीं करनी चाहिए कि आरवीओ किक करेगा या नहीं।
Matthieu M.

एनआरवीओ आम है (जैसा कि यूआरवीओ है) हालांकि यह एक गैर-मुद्दा है, जो कि निर्माण निर्माताओं के कारण है।
रप्त्ज

18

से सी ++ प्राइमर :

Istringstream प्रकार एक पढ़ता स्ट्रिंग , ostringstream एक लिखते स्ट्रिंग , और stringstream रीड और राईट स्ट्रिंग

मैं कुछ मामलों में आता हूं जहां यह दोनों सुविधाजनक और संक्षिप्त रूप से स्ट्रिंगस्ट्रीम का उपयोग करने के लिए है ।

मामला एक

यह से है समाधानों में से एक के लिए इस leetcode समस्या । यह एक बहुत ही उपयुक्त मामले को प्रदर्शित करता है जहां स्ट्रिंगस्ट्रीम का उपयोग कुशल और संक्षिप्त है।

मान लीजिए aऔर bस्ट्रिंग प्रारूप में व्यक्त जटिल संख्याएं हैं, हम स्ट्रिंग प्रारूप में aऔर उसके गुणन का परिणाम bभी प्राप्त करना चाहते हैं । कोड निम्नानुसार है:

string a = "1+2i", b = "1+3i";
istringstream sa(a), sb(b);
ostringstream out;

int ra, ia, rb, ib;
char buff;
// only read integer values to get the real and imaginary part of 
// of the original complex number
sa >> ra >> buff >> ia >> buff;
sb >> rb >> buff >> ib >> buff;

out << ra*rb-ia*ib << '+' << ra*ib+ia*rb << 'i';

// final result in string format
string result = out.str() 

मामला 2

यह एक लेटकोड समस्या से भी है, जिसके लिए आपको दिए गए पथ स्ट्रिंग को सरल बनाने की आवश्यकता है, जिसमें से एक का उपयोग करते हुए समाधान है जो मैंने देखा है सबसे सुंदर है:

string simplifyPath(string path) {
    string res, tmp;
    vector<string> stk;
    stringstream ss(path);
    while(getline(ss,tmp,'/')) {
        if (tmp == "" or tmp == ".") continue;
        if (tmp == ".." and !stk.empty()) stk.pop_back();
        else if (tmp != "..") stk.push_back(tmp);
    }
    for(auto str : stk) res += "/"+str;
    return res.empty() ? "/" : res; 
 }

स्ट्रिंगस्ट्रीम के उपयोग के बिना, इस तरह के संक्षिप्त कोड लिखना मुश्किल होगा।


2

आपने एक अल्फ़ान्यूमेरिक और इंट, रिक्त सीमांकित में प्रवेश किया mystr

आपने फिर पहले टोकन (रिक्त सीमांकित) को एक में बदलने का प्रयास किया int

पहला टोकन आरएस था, जो intमायप्राइस के लिए एक शून्य को छोड़ने में परिवर्तित करने में विफल रहा था , और हम सभी जानते हैं कि कुछ भी पैदावार शून्य समय है।

जब आप केवल दूसरी बार इंट वैल्यू में प्रवेश करते हैं, तो सब कुछ आपके द्वारा अपेक्षित रूप से काम करता है।

यह वह स्थानिक RS था जिसके कारण आपका कोड विफल हो गया था।

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