2010-03-09 16 views
6

से पढ़ें जब मैं कोडCIN या एक फ़ाइल

istream in; 
if (argc==1) 
     in=cin; 
else 
{ 
     ifstream ifn(argv[1]); 
     in=ifn; 
} 

जीसीसी विफल रहता है, शिकायत की कि operator= निजी है संकलित करने के लिए प्रयास करें। क्या किसी शर्त के आधार पर istream को अलग-अलग मानों पर सेट करने का कोई तरीका है?

उत्तर

4

आप किसी अन्य के साथ CIN के streambuf की जगह ले सकता है, और कुछ कार्यक्रमों इस के आसपास गुजर की सामान्य रणनीति से अधिक सरल है का जिक्र किए बिना istreams सीधे सीन।

int main(int argc, char* argv[]) { 
    ifstream input; 
    streambuf* orig_cin = 0; 
    if (argc >= 2) { 
    input.open(argv[1]); 
    if (!input) return 1; 
    orig_cin = cin.rdbuf(input.rdbuf()); 
    cin.tie(0); // tied to cout by default 
    } 

    try { 
    // normal program using cin 
    } 
    catch (...) { 
    if (orig_cin) cin.rdbuf(orig_cin); 
    throw; 
    } 

    return 0; 
} 

भले ही यह अत्यंत CIN के बाद नियंत्रण मुख्य छोड़ देता है उपयोग करने के लिए दुर्लभ है, इसके बाद के संस्करण कोशिश पकड़ अपरिभाषित व्यवहार से बचा जाता है कि अगर कुछ अपने कार्यक्रम कर सकता है।

+0

फ़ाइल को बाध्य करने के बाद सीट को टाई करना क्यों जरूरी है लेकिन कैच ब्लॉक में नहीं? – m42a

+0

@ m42a यह cout से _untied_ है। लेकिन मैं मानता हूं कि हम इसे वापस बांधना चाहते हैं। –

+0

@ m42a: ट्राइंग फ्लशिंग को प्रभावित करता है (सीन स्टडीन से सीन पढ़ने से पहले, यह कोउट फ्लश करता है) जब सीन को "रीडायरेक्ट" किया जाता है तो इसकी आवश्यकता नहीं होती है। ज्यादातर मामलों में, नियंत्रण के बाद मुख्य रूप से सीन से पढ़ने के लिए यह एक तर्क त्रुटि होगी, लेकिन कम से कम अगर आप स्ट्रीमबफ को पुनर्स्थापित करते हैं तो आप अपरिभाषित व्यवहार से बचेंगे (ifstream से filebuf नष्ट हो जाएगा)। यदि आप चाहें तो आप 'cin.tie (& cout)' का उपयोग कर सकते हैं। –

4

तो, क्या यह शिकायत नहीं कर रहा है "कोई उपयुक्त निर्माता उपलब्ध नहीं है"? वैसे भी, आप इसे नीचे के रूप में संशोधित कर सकते हैं।

void Read(istream& is) 
{ 
    string line; 
    while (getline(is, line)) 
     cout << line; 
} 

int main(int argc, char* argv[]) 
{ 
    if (argc == 1) 
     Read(cin); 
    else 
    { 
     ifstream in("sample.txt"); 
     Read(in); 
    } 
} 
+2

आपको यह समझाया जाना चाहिए कि आपने ऐसा क्यों किया है, न केवल कुछ कोड पोस्ट करें। स्ट्रीम ऑब्जेक्ट्स को प्रतिलिपि या असाइन नहीं किया जा सकता है, इसलिए आम तौर पर हम एक स्ट्रीम को एक गैर-संदर्भ संदर्भ के रूप में पास करते हैं क्योंकि हम इसे पढ़ने के लिए इच्छित आईओ ऑब्जेक्ट पास करते हैं या इसे लिखते हैं। –

+0

@Alexandros, सच। मुझे यह करना चाहिए था। – Jagannath

5

आप in के लिए एक सूचक इस्तेमाल कर सकते हैं, जैसे:

istream *in; 
ifstream ifn; 

if (argc==1) { 
    in=&cin; 
} else { 
    ifn.open(argv[1]); 
    in=&ifn; 
} 
1

आप इस तरह की धाराओं को प्रभावित नहीं कर सकते हैं। जो आप प्राप्त करना चाहते हैं उसे एक इशारा के लिए सूचक का उपयोग करके प्राप्त किया जा सकता है।

#include <fstream> 
#include <istream> 
#include <iostream> 

using namespace std; 

int main(int argc, char *argv[]) 
{ 
    istream *in; 
    // Must be declared here for scope reasons 
    ifstream ifn; 

    // No argument, use cin 
    if (argc == 1) in = &cin; 
    // Argument given, open the file and use it 
    else { 
    ifn.open(argv[1]); 
    in = &ifn; 
    } 
    return 0; 

    // You can now use 'in' 
    // ... 
} 
संबंधित मुद्दे