2009-03-02 12 views
8

से अहस्ताक्षरित चार पढ़ने मैं एक बाइनरी फ़ाइल से अहस्ताक्षरित बाइट्स पढ़ना चाहते हैं। इसलिए मैंने निम्नलिखित कोड लिखा था।सी ++ फ़ाइल धारा

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

std::string filename("file"); 
size_t bytesAvailable = 128; 
size_t toRead = 128; 

std::basic_ifstream<unsigned char> inf(filename.c_str(), std::ios_base::in | std::ios_base::binary) ; 
if (inF.good()) 
{ 
    std::vector<unsigned char> mDataBuffer; 
    mDataBuffer.resize(bytesAvailable) ; 
    inF.read(&mDataBuffer[0], toRead) ; 
    size_t counted = inF.gcount() ; 
} 

यह परिणाम 0 बाइट्स में हमेशा के रूप में पढ़ा जाता है जैसा वैरिएबल गिना जाता है।

वहाँ वेब कह मैं इस काम करने के लिए स्थान निर्धारित करने की आवश्यकता है कि पर संदर्भ होने लगते हैं। यह कैसे करें मुझे बिल्कुल स्पष्ट नहीं है।

एक ही कोड डेटा प्रकार 'अहस्ताक्षरित चार'

ऊपर कोड अहस्ताक्षरित चार विंडोज पर काम करने के लिए लगता है का उपयोग कर के बजाय 'चार' का उपयोग कर काम करता है लेकिन एक colinux फेडोरा 2.6.22.18 में चल विफल रहता है।

क्या मैं इसे लिनक्स के लिए काम करने के लिए पाने के लिए क्या करना होगा?

+0

सवाल का एक जवाब नहीं है, लेकिन संबंधित।याद रखें कि सी ++ में स्ट्रिंग क्लास की परिभाषा 'typedef basic_string स्ट्रिंग है; ', ताकि आप हमेशा एक हस्ताक्षरित चार स्ट्रिंग क्लास ला ला टाइपिफ मूल_स्ट्रिंग bytestring;' बना सकें। –

+0

सच है, लेकिन मैं एक बिनरी फ़ाइल – David

+0

पढ़ना चाहता हूं .read() और .write() बाइनरी/टेक्स्ट के लिए उपयोग किया जा सकता है, स्ट्रीम ऑपरेटर << and >> केवल टेक्स्ट फ़ाइलों के लिए हैं। कंप्यूटर पर सभी डेटा अंततः द्विआधारी है, इस तरह आप इसे समझना चुनते हैं। – sfossen

उत्तर

15

सी ++ केवल चरित्र लक्षण के दो संस्करणों के लिए स्पष्ट विशेषज्ञताओं प्रदान करने के लिए कार्यान्वयन की आवश्यकता होती है:

std::char_traits<char> 
std::char_traits<wchar_t> 

नदियों और तार उन लक्षण का उपयोग एक किस्म यह पता लगाने की चीजों की, EOF मूल्य, वर्ण की एक श्रृंखला की तुलना, एक पूर्णांक के लिए एक चरित्र का चौड़ा करने, और इस तरह सामान की तरह।

आप की तरह

std::basic_ifstream<unsigned char> 

एक धारा तुम्हें यकीन एक इसी चरित्र विशेषता विशेषज्ञता है कि धारा का उपयोग कर सकते है कि वहाँ करना है और इस विशेषज्ञता उपयोगी बातें करते है कि दृष्टांत हैं। इसके अलावा, स्ट्रीम वास्तविक स्वरूपण और संख्याओं को पढ़ने के लिए पहलुओं का उपयोग करते हैं। इसी प्रकार आपको उन लोगों के विशेषज्ञ भी प्रदान करना होगा। मानक को प्राथमिक टेम्पलेट की पूरी परिभाषा रखने के लिए कार्यान्वयन की भी आवश्यकता नहीं होती है।

error: specialization std::char_traits could not be instantiated.

मैं का प्रयोग करेंगे ifstream बजाय (जो एक basic_ifstream<char> है) और फिर जाने के लिए और एक vector<char> में पढ़ा: तो आप अच्छी तरह से एक संकलन त्रुटि मिल सकता है। जब वेक्टर में डेटा की व्याख्या, आप अभी भी उन unsigned char को बाद में बदल सकते हैं।

+3

मुझे एक कंपाइलर त्रुटि नहीं मिली, दस्तावेज में कोई संकेत नहीं, कुछ भी नहीं, लेकिन चुप विफलता और बर्बाद दिन। धन्यवाद Bjarne Stroustrup और डेनिस रिची। – user1358

13

basic_ifstream का उपयोग के रूप में यह specializtion की आवश्यकता है।

एक स्थिर बफर का उपयोग करना:

linux ~ $ cat test_read.cpp 
#include <fstream> 
#include <iostream> 
#include <vector> 
#include <string> 


using namespace std; 

int main(void) 
{ 
     string filename("file"); 
     size_t bytesAvailable = 128; 

     ifstream inf(filename.c_str()); 
     if(inf) 
     { 
       unsigned char mDataBuffer[ bytesAvailable ]; 
       inf.read((char*)(&mDataBuffer[0]), bytesAvailable) ; 
       size_t counted = inf.gcount(); 
       cout << counted << endl; 
     } 

     return 0; 
} 
linux ~ $ g++ test_read.cpp 
linux ~ $ echo "123456" > file 
linux ~ $ ./a.out 
7 

एक सदिश का उपयोग कर:

linux ~ $ cat test_read.cpp 

#include <fstream> 
#include <iostream> 
#include <vector> 
#include <string> 


using namespace std; 

int main(void) 
{ 
     string filename("file"); 
     size_t bytesAvailable = 128; 
     size_t toRead = 128; 

     ifstream inf(filename.c_str()); 
     if(inf) 
     { 

       vector<unsigned char> mDataBuffer; 
       mDataBuffer.resize(bytesAvailable) ; 

       inf.read((char*)(&mDataBuffer[0]), toRead) ; 
       size_t counted = inf.gcount(); 
       cout << counted << " size=" << mDataBuffer.size() << endl; 
       mDataBuffer.resize(counted) ; 
       cout << counted << " size=" << mDataBuffer.size() << endl; 

     } 

     return 0; 
} 
linux ~ $ g++ test_read.cpp -Wall -o test_read 
linux ~ $ ./test_read 
7 size=128 
7 size=7 

बजाय पहली कॉल में आकार बदलने के रिजर्व का उपयोग कर:

linux ~ $ cat test_read.cpp 

#include <fstream> 
#include <iostream> 
#include <vector> 
#include <string> 


using namespace std; 

int main(void) 
{ 
     string filename("file"); 
     size_t bytesAvailable = 128; 
     size_t toRead = 128; 

     ifstream inf(filename.c_str()); 
     if(inf) 
     { 

       vector<unsigned char> mDataBuffer; 
       mDataBuffer.reserve(bytesAvailable) ; 

       inf.read((char*)(&mDataBuffer[0]), toRead) ; 
       size_t counted = inf.gcount(); 
       cout << counted << " size=" << mDataBuffer.size() << endl; 
       mDataBuffer.resize(counted) ; 
       cout << counted << " size=" << mDataBuffer.size() << endl; 

     } 

     return 0; 
} 
linux ~ $ g++ test_read.cpp -Wall -o test_read 
linux ~ $ ./test_read 
7 size=0 
7 size=7 

आप देख सकते हैं, बिना .resize (गिनती) पर कॉल करें, वेक्टर का आकार गलत होगा। कृपया यह ध्यान में रखें। इसका इस्तेमाल करने के कास्टिंग को देखने के लिए एक आम बात है cppReference

+0

का पूर्ण कार्यान्वयन है। यह हस्ताक्षरित वर्ण पढ़ रहा है। मुझे यह काम पता है। मैं विशेष रूप से हस्ताक्षरित वर्णों को पढ़ना चाहता हूं – David

+0

बस char [] को हस्ताक्षरित char [] में बदलें। – sfossen

+0

और कलाकार जोड़ें: पी – sfossen

0

एक बहुत ही आसान तरीका:

#include <fstream> 
#include <vector> 

using namespace std; 


int main() 
{ 
    vector<unsigned char> bytes; 
    ifstream file1("main1.cpp", ios_base::in | ios_base::binary); 
    unsigned char ch = file1.get(); 
    while (file1.good()) 
    { 
     bytes.push_back(ch); 
     ch = file1.get(); 
    } 
    size_t size = bytes.size(); 
    return 0; 
} 
+0

यह बहुत अक्षम है। 1 जीबी फाइलों के साथ बेंचमार्क चलाने का प्रयास करें, कॉल के ओवरहेड में एक बड़ा अंतर दिखाई देगा। – sfossen

+0

यह क्यों काम करता है लेकिन पढ़ने के लिए कॉल विफल रहता है? – David

+0

क्योंकि फ़ाइल एक हस्ताक्षरित चार है !!!! मुझे यह देखना चाहिए था। – David