2010-10-07 13 views
5

std::istream प्रोटोटाइप istream& read (char* s, streamsize n) है वास्तविक बाइट्स पढ़ने की संख्या istream::gcount(), यह भी istream की वैधता ios::good से जाना जा सकता है फोन करके मिल जाना चाहिए।std :: IStream के डिजाइन :: समझना पढ़

मैं एक और धारा वर्ग के कार्यान्वयन पर चर्चा कर रहा था, मैं अपने सहयोगी के साथ लिखने की कोशिश कर रहा था, जहां मैं कह रहा था कि मैं इस डिजाइन का पालन कर सकता हूं; लेकिन उन्होंने कहा कि उपयोगकर्ता को gcount हर बार कॉल करने के बजाय, istream& read (char* s, streamsize n, size_t &bytes_read) की तरह पढ़ा गया प्रोटोटाइप हो सकता है ताकि यह एक ही कॉल में खत्म हो जाये और पूर्व बेकार हो। मैं std की डिज़ाइन पसंद की रक्षा करने में असमर्थ था। istream::read के पीछे असली तर्क क्या है?

+0

क्या आपका मतलब है 'size_t & bytes_written'? और, यह शायद 'streamsize और bytes_written' (या शायद' chars_read') होना चाहिए। –

+0

@ जेम्स: हाँ, धन्यवाद! बाइट्स और वर्ण समानार्थी _here_ हैं, क्योंकि 'sizeof' वही है :) – legends2k

उत्तर

4

मुझे लगता है कि ऐसा इसलिए है क्योंकि सी ++ आमतौर पर एक इंटरफ़ेस को मजबूर नहीं करता है जिसे हर किसी के लिए आवश्यक नहीं हो सकता है। यदि आपको ऐसे पैरामीटर को स्वीकार करने के लिए read की आवश्यकता है जो कुछ लोगों की परवाह नहीं करते हैं, तो यह अतिरिक्त कोडिंग कार्य (पैरामीटर के रूप में पास करने के लिए अतिरिक्त int घोषित करता है) का कारण बनता है। यह हमेशा बाइट्स को सहेजता है चाहे इस पर ध्यान दिए बिना कि ग्राहक क्या परवाह करता है या नहीं (कुछ क्लाइंट केवल यह ध्यान रख सकते हैं कि पढ़ना विफल हो गया है जैसा कि ईओएफ/असफल बिट्स द्वारा इंगित किया गया है)।

एक अलग विधि के साथ आप जानकारी के विभिन्न टुकड़ों के लिए इंटरफ़ेस को दोहराते हैं जिनकी आवश्यकता हो सकती है या नहीं।

0

std::istream प्रोटोटाइप istream& read (char* s, streamsize n) है वास्तविक बाइट की संख्या पढ़ा istream::gcount() बुला, यह भी वैधता istream की ios::good से जाना जा सकता है द्वारा मिल जाना चाहिए।

istream::read(char* s, streamsize n) एक अस्वरूपित s पर सरणी में आकार n के डेटा के ब्लॉक (NULL समाप्ति के बिना) पढ़ता है। भले ही schar पर एक सूचक है, तो आप बाइनरी डेटा पढ़ने के लिए istream::read का उपयोग कर सकते हैं। उदाहरण के लिए, यदि आप एक istream कि युगल (यह मानते हुए कि endianness सही है) की एक सरणी के मूल्यों रखती हो सकता है:

unsigned int count; 
input.read(reinterpret_cast<char*>(&count), sizeof(count)); 
double* data = new double[count]; 

for (unsigned int i = 0; i < count; ++i) 
    input.read(reinterpret_cast<char*>(data[i]), sizeof(double)); 

istream::gcount() पिछले istream::read कॉल में पढ़े गए बाइट की संख्या दिखाता है। इस मामले में, हम देखते हैं कि count का आकार double के आकार से शायद अलग है, इसलिए हम data सरणी में पहले तत्व के आकार को निर्दिष्ट करने के लिए istream::gcount() का उपयोग करने में सक्षम नहीं होंगे।

+0

@CashCow 'istream :: read' की सीमाओं का सही समाधान है। मैं ऊपर नहीं जा सकता क्योंकि मेरे पास प्रतिष्ठा के कम से कम 15 अंक नहीं हैं (मैं अभी भी एक स्टैक ओवरफ़्लो एन 00 बी हूं)। –

+0

मेरा वास्तविक सवाल था, हमें 'gcount' को कॉल करने की आवश्यकता क्यों है; इसके बजाय ऐसा क्यों नहीं है कि कॉलर एक रिफर्न्स वैरिएबल पास कर सकता है, जिसे कॉलर कॉलिंग gcount के बजाय वास्तव में पढ़ने वाले बाइट्स की संख्या के लिए 'read' द्वारा सेट किया जाएगा) जो कि' स्ट्रीमसाइज एन' से कम या बराबर हो सकता है) हर बार। – legends2k

+0

@CashCow के रूप में पढ़ा गया बाइट्स की संख्या को वापस करने के लिए बेहतर लगता है 'istream :: readsome' के साथ समझाया गया है। जैसा कि @ मार्क बी ने समझाया, यह संदर्भ द्वारा पारित करने के लिए एक अतिरिक्त int घोषित करने से बचाता है। एक अन्य विकल्प वेरिएबल को पॉइंटर पास कर रहा है जिसे 'NULL' के लिए डिफॉल्ट किया गया है, जिसका प्रयोग बाइट्स की वास्तविक संख्या को अनदेखा करने के लिए किया जा सकता है: 'istream और read (char * s, streamsize n, streamsize * bytesRead = NULL) '। हालांकि, मुझे नहीं पता कि यह 'istream :: readsome' पर एक महत्वपूर्ण लाभ प्रदान करेगा या नहीं। –

2

readsome आदेश के बजाय की कोशिश करें,

streamsize readsome (char* buf, streamsize num); 

buf अपने बफर और संख्या है बाइट की संख्या आप पढ़ना चाहते हैं, अपने बफर में उपलब्ध बाइट्स, ज़ाहिर है की ज्यादा से ज्यादा संख्या है।

वापसी मूल्य बाइट्स की संख्या वास्तव में पढ़ा जाता है।

समाप्त करने के लिए एक फ़ाइल को पढ़ने के लिए आप कर सकते हैं पाश:

char buf[BUF_SIZE] 
streamsize bytesRead; 
do 
{ 
    bytesRead = instr.readsome(buf, BUF_SIZE); 
    // do stuff with the bytes you read, if any 
} while (bytesRead == BUF_SIZE); 
0

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

कैश गाय के समाधान के जवाब में, मुझे लगता है कि एक बग है। यदि आप आईओ पर इंतजार कर रहे हैं और बफर को आंशिक रूप से भरने के लिए पर्याप्त वर्ण हैं, तो फ़ंक्शन वापस आ जाएगा और फ़ाइल पूरी तरह से पढ़ने से पहले जबकि लूप समाप्त हो जाएगा। तो यदि सीधे कच्चे आईओ के शीर्ष पर लिखा गया तो उसका समाधान शायद सही ढंग से चलाया जाएगा, लेकिन buffered IO पर चलने में विफल रहेगा।

सही समाधान, निश्चित रूप से, ईओएफ ध्वज सेट होने पर लूप को समाप्त करना होगा। मुझे यकीन नहीं है कि इस समय बैडबिट सेट होने पर सबसे अच्छी प्रतिक्रिया क्या होती है, लेकिन आपको शायद उस मामले को भी संभालना चाहिए।

मैं सहमत हूं कि पढ़ना पढ़ने के लिए एक सभ्य विकल्प है, हालांकि।

संपादित करें: कभी-कभी पढ़ना उपलब्ध नहीं है (कुछ वीसी ++ संस्करण)। इस मामले में, पढ़ना अनुपयोगी नहीं है।

संबंधित मुद्दे