2009-05-04 9 views
42

आप Windows अनुप्रयोग के लिए सी ++ मानक लाइब्रेरी का उपयोग कर फ़ाइल खोलने के रूप में कुछ मूलभूत कल्पना नहीं करेंगे ... लेकिन ऐसा प्रतीत होता है। यूनिकोड द्वारा मेरा मतलब यूटीएफ -8 है, लेकिन मैं यूटीएफ -16 में परिवर्तित कर सकता हूं या जो भी हो, पॉइंट को यूनिकोड फ़ाइल नाम से ऑफस्ट्रीम उदाहरण मिल रहा है। अपने स्वयं के समाधान को हैक करने से पहले, क्या यहां कोई पसंदीदा मार्ग है? विशेष रूप से एक क्रॉस प्लेटफार्म एक?एक यूनिकोड फ़ाइल नाम के साथ std :: fstream (ऑफस्ट्रीम या ifstream) कैसे खोलें?

+0

मैं इस एक [डुप्लिकेट] (http://stackoverflow.com/questions/480849/windows-codepage-interactions-with-standard-cc-filenames) सवाल। देखें कि क्या कोई जवाब मदद कर सकता है। –

+0

आप डेटा प्रकारों का उपयोग क्यों नहीं करते हैं जैसे 'std :: wofstream'? ** डब्ल्यू ** ध्यान दें! – sergiol

उत्तर

51

सी ++ मानक पुस्तकालय यूनिकोड-जागरूक नहीं है। char और wchar_t यूनिकोड एन्कोडिंग होने की आवश्यकता नहीं है।

Windows पर, wchar_t UTF-16 है, लेकिन मानक पुस्तकालय में UTF-8 फ़ाइल नामों के लिए कोई सीधा समर्थन (char डेटाप्रकार विंडोज पर यूनिकोड नहीं है)

MSVC के साथ

(और इस तरह माइक्रोसॉफ्ट एसटीएल) वहाँ , filestreams के लिए एक निर्माता प्रदान की जाती है जो एक const wchar_t* फ़ाइल नाम लेता है, आप के रूप में स्ट्रीम बनाने के लिए अनुमति देता है:

wchar_t const name[] = L"filename.txt"; 
std::fstream file(name); 

हालांकि, इस अधिभार सी ++ 11 मानक द्वारा निर्दिष्ट नहीं है (यह केवल की उपस्थिति की गारंटी देता है char आधारित संस्करण)। यह वैकल्पिक जीटीएल कार्यान्वयन पर भी मौजूद नहीं है जैसे जीसीसी के libstdC++ MinGW (-w64) के लिए, संस्करण g ++ 4.8.x के रूप में।

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

+0

"fstream दोनों wchar_t ... को स्वीकार करने की गारंटी है" का क्या मतलब है? मेरे पास आधिकारिक 98 मानक तक पहुंच नहीं है, लेकिन n2857 में मूल_फस्ट्रीम के लिए wchar_t * ctor का उल्लेख नहीं मिल सकता है (यानी, IIUC, वर्तमान C++ 0x कार्य ड्राफ्ट) –

+0

हम्म, ऐसा लगता है कि आप सही हैं । मैं – jalf

+0

@ एरिक को सही मानता हूं: सहमत हूं, basic_fstream के लिए रचनाकारों को '03 मानक के 27.8.1.12 में परिभाषित किया गया है, और दो हैं: नो-Args और char *।fstream एक basic_fstream है, और उस विशेषज्ञता के लिए परिभाषित कोई अतिरिक्त सदस्य नहीं हैं। –

3

विज़ुअल सी ++ के वर्तमान संस्करण std :: basic_fstream में open() विधि है जो http://msdn.microsoft.com/en-us/library/4dx08bh4.aspx के अनुसार wchar_t * लेती है।

+0

क्या यह अंततः/सैद्धांतिक रूप से पोर्टेबल होगा? –

+3

सभी ओएस और फ़ाइल सिस्टम यूनिकोड फ़ाइल नामों का समर्थन नहीं करते हैं, इसलिए यह पोर्टेबल नहीं होगा। जो मैं इकट्ठा कर सकता हूं उससे fcharream पर wchar_t * open() और कन्स्ट्रक्टर माइक्रोसॉफ्ट एक्सटेंशन हैं क्योंकि एनटीएफएस यूनिकोड फ़ाइल नामों का समर्थन करता है। –

+3

या इसके बजाय, क्योंकि एनटीएफएस यूनिकोड फ़ाइल नामों को एन्कोड करने के लिए यूटीएफ 16 का उपयोग करता है। लिनक्स यूनिकोड फ़ाइल नामों का भी समर्थन करता है, लेकिन यूटीएफ 8 का उपयोग करता है, इसलिए नियमित चार * संस्करण वहां काम करता है – jalf

1

std::wofstream, std::wifstream और std::wfstream का उपयोग करें। वे यूनिकोड फ़ाइल नाम स्वीकार करते हैं। फ़ाइल का नाम wstring होना चाहिए, wchar_t एस की सरणी, या पाठ से पहले _T() मैक्रो, या उपसर्ग L होना चाहिए।

+0

क्या आप 'यूनिकोड' होने के नाते 'std :: wfstream' के साक्ष्य प्रदान कर सकते हैं? मेरे सामान्य ज्ञान तक, वे केवल 'wchar_t' का उपयोग करते हैं जो एक विस्तृत चरित्र है, आमतौर पर' 16-बिट्स '। लेकिन सामग्री 'यूनिकोड' हो सकती है या नहीं। –

+0

मेरा मतलब यह था कि वे यूनिकोड स्ट्रिंग स्वीकार करते हैं, जो सवाल का जवाब देते हैं, है ना? – Brackets

+0

वास्तव में यह प्रश्न का आधा जवाब देता है: मान लीजिए कि आपको अपने फ़ाइल पथ UTF16 को आपके wfstream (या आपके fstream में UTF8) में मिला है। विंडोज़ यूनिकोड स्वीकार नहीं करते हैं और यदि आपके पास कुछ विशेष वर्ण हैं (उदाहरण के लिए चीनी) तो "गलत यूआरएल" वापस आ जाएगा। –

0

Boost.Nowide पर एक नज़र डालें:

#include <boost/nowide/fstream.hpp> 
#include <boost/nowide/cout.hpp> 
using boost::nowide::ifstream; 
using boost::nowide::cout; 

// #include <fstream> 
// #include <iostream> 
// using std::ifstream; 
// using std::cout; 

#include <string> 

int main() { 
    ifstream f("UTF-8 (e.g. ß).txt"); 
    std::string line; 
    std::getline(f, line); 
    cout << "UTF-8 content: " << line; 
} 
संबंधित मुद्दे