2008-10-02 14 views
5

मुझे फ़ाइल से डेटा पढ़ने में थोड़ी सी समस्या है। मैं wstring के पढ़ने के साथ-साथ मनमाने ढंग से आकार के कच्चे डेटा के एक हिस्से के रूप में पढ़ने में सक्षम होना चाहता हूं (आकार बाइट्स में है)।मैं wfstream से बाइनरी डेटा कैसे पढ़ सकता हूं?

std::wfstream stream(file.c_str()); 

std::wstring comType; 
stream >> comType; 

int comSize; 
stream >> comSize; 

char *comData = new char[comSize]; 
memset(comData, 0, comSize); 
stream.read(comData, comSize); 
//error C2664 : 'std::basic_istream<_Elem,_Traits>::read' 
//   : cannot convert parameter 1 from 'char *' to 'wchar_t *' 

शायद मैं गलत धाराओं या उन पंक्तियों के साथ कुछ उपयोग कर रहा हूं। असल में, मैं एक wstring, डेटा के आकार का आकार (जो बाइट्स की संख्या हो सकती है) पढ़ना चाहते हैं, उसके बाद घटक डेटा के कई बाइट्स। जाहिर है, मैं char को नहीं पढ़ सकता क्योंकि टेम्पलेट wchar_t का मानता है।

मैं wchar_t को पढ़ सकता हूं लेकिन फिर मुझे यह सुनिश्चित करना होगा कि डेटा आकार (wchar_t) द्वारा गठबंधन के रूप में संग्रहीत किया गया हो। अन्यथा, मैं धारा को दूषित कर सकता हूं। एक परिदृश्य तब होगा जब डेटा 15 बाइट्स होगा। मुझे 16 बाइट्स पढ़ना होगा, फिर अनचाहे बाइट मास्क करना होगा, अगले डेटा खंड को पढ़ने में सक्षम होने के लिए स्ट्रीम को 15 बाइट ऑफसेट (यदि संभव हो तो wchar_t templated?) के लिए स्ट्रीम की तलाश करें।

स्पष्ट रूप से, जो मैं करने की कोशिश कर रहा हूं उसे प्राप्त करने का एक अच्छा तरीका होना चाहिए।

+2

क्या यह सिर्फ मुझे है या किसी और ने डब्ल्यूटीएफस्ट्रीम भी पढ़ा है? :-) – VVS

उत्तर

1

अपनी आवश्यकताओं को ध्यान में रखते हुए मुझे नहीं लगता कि wfstream जाने का तरीका है। निम्नलिखित कोड स्निपेट की तरह कुछ का उपयोग करने वाले विचारकर्ता।

#include "stdafx.h" 
#include <fstream> 
#include <iostream> 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    std::wstring str(L"hello"); 
    size_t size1 = str.length(); 
    char data[] = { 0x10, 0x20, 0x30 }; 
    size_t size2 = 3; 

    FILE* output = NULL; 
    if (_wfopen_s(&output, L"c:\\test.bin", L"wb") == 0) { 
     fwrite(&size1, sizeof(size_t), 1, output); 
     fwrite(str.c_str(), size1 * sizeof(wchar_t), 1, output); 
     fwrite(&size2, sizeof(size_t), 1, output); 
     fwrite(data, size2, 1, output); 

     fclose(output); 
    } 

    FILE* input = NULL; 
    if (_wfopen_s(&input, L"c:\\test.bin", L"rb") == 0) { 
     fread(&size1, sizeof(size_t), 1, input); 
     wchar_t* wstr = new wchar_t[size1 + 1]; 
     fread(wstr, size1 * sizeof(wchar_t), 1, input); 
     std::wstring str(wstr, size1); 
     delete[] wstr; 
     fread(&size2, sizeof(size_t), 1, input); 
     char* data1 = new char[size2]; 
     fread(data1, size2, 1, input); 

     std::wcout << str.c_str() << std::endl; 
     for (size_t i = 0; i < size2; ++i) { 
      std::wcout << std::hex << "0x" << int(data1[i]) << std::endl; 
     } 

     delete[] data1; 

     fclose(input); 
    } 

    return 0; 
} 

यह आउटपुट:

hello 
0x10 
0x20 
0x30 
+0

मुझे लगता है कि बदलती पद्धति एक बहुत बड़ा सौदा करने में मदद करता है। स्निपेट के लिए धन्यवाद। – Statement

2

stream.read के साथ समस्या यह है कि यह wfstream के साथ "चरित्र इकाई" के रूप में wchar_t का उपयोग करता है। यदि आप fstream का उपयोग करते हैं तो यह char को "वर्ण इकाई" के रूप में उपयोग करता है।

यह आपको विस्तृत वर्णों पढ़ना चाहते हैं काम करेगा:

wchar_t *comData = new wchar_t[comSize]; 
stream.read(comData, comSize); 

इसके अलावा डेटा के 15 बाइट्स एक विस्तृत धारा के साथ पढ़ा नहीं जा सकता है, क्योंकि सबसे छोटी इकाई से कम 2bytes पर है (नीचे देखें), तो आप केवल sizwof (wchar_t) * n के टुकड़े पढ़ सकते हैं।

लेकिन यदि आप एप्लिकेशन की पोर्टेबिलिटी के बारे में चिंतित हैं wfstream/wchar_t शायद सबसे अच्छा समाधान नहीं है क्योंकि कोई मानक नहीं है कि wchar_t कितना व्यापक है (उदाहरण के लिए विंडोज़ wchar_t कई यूनिक्स/लिनक्स सिस्टम पर 16 बिट है, यह 32 बिट है)।

टेक्स्ट को विस्तृत वर्णों के रूप में संग्रहीत करने में दूसरी समस्या अंतहीन है, मैं टेक्स्ट स्टोरेज के लिए यूटीएफ -8 का उपयोग करने का सुझाव दूंगा।

+0

अच्छा अंक। मैंने कुछ समय पहले व्यापक चौकों को छोड़ दिया था। कोडिंग में बहुत अधिक समय लगा, कोड अस्पष्ट हो गया, और हमने फैसला किया कि स्ट्रिंग के लिए नियमित वर्णों के साथ चिपकने में कोई समस्या नहीं थी। – Statement

+0

वाईफस्ट्रीम स्ट्रीम से संकीर्ण वर्ण पढ़ेगा। (जब तक आप सुझाव देते हैं, कच्चे वर्ण पढ़ते हैं)। हर कोई इसे व्यापक वर्ण पढ़ने की उम्मीद करता है, लेकिन वास्तविकता यह है कि यह नहीं है। उदाहरण के लिए, आप wifars में कनवर्ट करने के लिए वाईफस्ट्रीम और एक कोडेकैट पहलू का उपयोग करके यूटीएफ -8 पढ़ सकते हैं। यूटीएफ -16 फाइलों को संभालना आपके विचार से ज्यादा जटिल है। – Pete

0
# ifdef UNICODE 
#  define tfstream wfstream 
# else 
#  define tfstream fstream 
# endif 

tfstream fs(_T("filename.bin"), tfstream::binary); 
byte buffer[1023]; 
fs.read(buffer, sizeof(buffer)) 

मुझे लगता है कि, _T ("filename.bin") और tfstream यूआई अभिव्यक्ति है; बफर और पढ़ा() डेटा लॉजिक अभिव्यक्ति है। wfstream को बफर को wchar_t प्रकार तक सीमित नहीं करना चाहिए। UI को डेटा लॉजिक के साथ मिश्रण नहीं करना चाहिए! wfstream यहाँ गलत बात करें

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