2010-12-17 7 views
6

मेरे पास एक ऐसा फ़ंक्शन है जिसके लिए मुझे एक char * द्वारा इंगित यूटीएफ -8 स्ट्रिंग पास करने की आवश्यकता होती है, और मेरे पास एक सिंगल बाइट के लिए चार पॉइंटर है स्ट्रिंग। मैं स्ट्रिंग को सी ++ में यूटीएफ -8 एन्कोडिंग में कैसे परिवर्तित कर सकता हूं? क्या ऐसा कोई कोड है जिसका उपयोग मैं कर सकता हूं? धन्यवाद!एक एकल-बाइट कॉन्स char * को एक यूटीएफ -8 एन्कोडिंग में परिवर्तित करने के लिए कैसे करें

+7

आपकी मूल स्ट्रिंग क्या एन्कोडिंग है? – ybungalobill

+0

स्ट्रिंग को फाइल सिस्टम पर फ़ाइलों के पथ और नाम पढ़ने के लिए रीडडियर को कॉल से लिया गया है। तो, मुझे नहीं पता कि यह क्या एन्कोडिंग है। लेकिन मुझे लगता है कि यह ऐसा कुछ करने से अलग नहीं है: char * string = "कुछ अजीब स्ट्रिंग जैसे è"। –

+0

लिनक्स पर पथनाम किसी दिए गए एन्कोडिंग को लागू नहीं करता है, केवल नियम यह है कि इसमें कोई/नहीं हो सकता है। इस प्रकार, कोई भी किसी भी एन्कोडिंग का उपयोग करके फ़ाइल नाम बना सकता है, या यहां तक ​​कि एक फ़ाइल नाम जो अवैध रूप से किसी दिए गए वर्णमाला में एन्कोड किया गया हो। आप अनुमान लगा सकते हैं कि यह ISO8859-1 है और इसे iconv() फ़ंक्शन के साथ बदल दें। – nos

उत्तर

2

सुझाव एक अलग वर्ण एन्कोडिंग के लिए एक स्ट्रिंग परिवर्तित करने के लिए का उपयोग कर परिवर्तित कर सकते हैं, विभिन्न वर्ण एन्कोडिंग पुस्तकालयों में से किसी का उपयोग करें। एक लोकप्रिय पसंद iconv (अधिकांश लिनक्स सिस्टम पर मानक) है।

हालांकि, ऐसा करने के लिए आपको पहले अपने इनपुट के एन्कोडिंग को समझने की आवश्यकता है। दुर्भाग्य से इसका कोई सामान्य समाधान नहीं है। यदि इनपुट अपने एन्कोडिंग को निर्दिष्ट नहीं करता है (जैसे कि वेब पेज आमतौर पर करते हैं), तो आपको अनुमान लगाना होगा।

आपके प्रश्न के अनुसार: आप लिखते हैं कि आपको FAT32 फ़ाइल सिस्टम पर readdir पर कॉल करने से स्ट्रिंग मिलती है। मुझे पूरा यकीन नहीं है, लेकिन मेरा मानना ​​है कि readdir फ़ाइल नामों को फाइल सिस्टम द्वारा संग्रहीत कर देगा।FAT/FAT32 के मामले में:

  • लघु फ़ाइल नाम कुछ डॉस code page में इनकोड - जो कोड पेज कैसे फ़ाइलों जहां लिखा पर निर्भर करता है, वहाँ कोई रास्ता नहीं है बस फाइल सिस्टम AFAIK से बताने के लिए है।
  • लंबे फ़ाइल नाम यूटीएफ -16 में हैं।

आप FAT32 विभाजन तक पहुँचने के लिए मानक vfat लिनक्स कर्नेल मॉड्यूल का उपयोग करते हैं, तो आप readdir से लंबे फ़ाइल नाम मिलना चाहिए (जब तक कि एक फ़ाइल केवल 8.3 नाम है)। इन्हें यूटीएफ -16 के रूप में डीकोड किया जा सकता है। FAT32 आंतरिक रूप से यूटीएफ -16 में लंबे फ़ाइल नामों को स्टोर करता है। vfat ड्राइवर उन्हें iocharset= माउंट पैरामीटर (डिफ़ॉल्ट रूप से डिफ़ॉल्ट सिस्टम एन्कोडिंग होने पर, मुझे विश्वास है) द्वारा दिए गए एन्कोडिंग में परिवर्तित कर देगा।

अतिरिक्त जानकारी:

आप सही FAT32 वॉल्यूम पर फ़ाइल नाम पाने के लिए माउंट विकल्प codepage और iocharset (http://linux.die.net/man/8/mount देखें) के साथ खेलने के लिए हो सकता है। इस तरह माउंट करने का प्रयास करें कि लिनक्स कंसोल में फ़ाइल नाम सही तरीके से दिखाए जाते हैं, फिर आगे बढ़ें। यहां कुछ और स्पष्टीकरण दिया गया है: http://www.nslu2-linux.org/wiki/HowTo/MountFATFileSystems

+0

अंतिम लिंक ने मेरी विशिष्ट समस्या का समाधान किया। ऐसा लगता है कि डिवाइस को उचित पैरामीटर के साथ सही तरीके से काम करने के लिए माउंट करने के लिए पर्याप्त था। मैं इसे स्वीकार किए गए उत्तर के रूप में चिह्नित करता हूं क्योंकि यह मेरी विशिष्ट स्थिति को हल करता है और यह सामान्य मामले को सही तरीके से समझाता है। वैसे भी सभी के लिए धन्यवाद! –

4

लिनक्स मानते हुए, आप iconv देख रहे हैं। जब आप कनवर्टर (iconv_open) खोलते हैं, तो आप और से एन्कोडिंग पास करते हैं। यदि आप से खाली स्ट्रिंग पास करते हैं, तो यह आपके सिस्टम पर उपयोग किए गए लोकेल से कनवर्ट होगा जो फ़ाइल सिस्टम से मेल खाना चाहिए।

विंडोज़ पर, आपके पास MultiByteToWideChar के साथ बहुत कुछ है जहां आप CP_ACP को कोडपृष्ठ के रूप में पास करते हैं। लेकिन विंडोज़ पर आप यूनिकोड को तुरंत प्राप्त करने के लिए फ़ंक्शंस के यूनिकोड संस्करण को कॉल कर सकते हैं और फिर WideCharToMultiByte और CP_UTF8 के साथ यूटीएफ -8 में कनवर्ट कर सकते हैं।

1

मुझे लगता है कि शीर्ष बिट 1 बाइट स्ट्रिंग पर सेट है, इसलिए जिस फ़ंक्शन को आप पास कर रहे हैं वह 1 बाइट से अधिक होने की उम्मीद कर रहा है।

सबसे पहले, हेक्स में स्ट्रिंग को प्रिंट करें।

अर्थात

unsigned char* str = "your string"; 
for (int i = 0; i < strlen(str); i++) 
    printf("[%02x]", str[i]); 

अब UTF8 एन्कोडिंग पर विकिपीडिया लेख जो यह अच्छी तरह से बताते हैं की एक पढ़ा है।
http://en.wikipedia.org/wiki/UTF-8

यूटीएफ -8 चर चौड़ाई है जहां प्रत्येक चरित्र 1 से 4 बाइट्स पर कब्जा कर सकता है।

इसलिए हेक्स को बाइनरी में परिवर्तित करें और देखें कि कोड बिंदु क्या है।

यानी यदि पहला बाइट 11110 (बाइनरी में) शुरू होता है तो यह 4 बाइट स्ट्रिंग की अपेक्षा करता है। चूंकि एएससीआई 7-बिट 0-127 है, इसलिए शीर्ष बिट हमेशा शून्य होता है इसलिए केवल 1 बाइट होना चाहिए। वैसे, एक यूटीएफ 8 स्ट्रिंग के विस्तृत चरित्र में पहले बाइट के बाद बाइट शीर्ष बिट्स के लिए "10 ..." शुरू करेंगे। ये निरंतर बाइट्स हैं ... यही है कि आपका फ़ंक्शन किस बारे में शिकायत कर रहा है ... यानी जब अपेक्षित बाइट्स अनुपलब्ध हों तो अपेक्षित हो। तो स्ट्रिंग बिल्कुल सच नहीं है जैसा कि आपने सोचा था कि यह था।

आप के रूप में किसी को iconv, या शायद इस पुस्तकालय http://utfcpp.sourceforge.net/

+0

मैंने स्ट्रिंग "/ system/mnt/usb0/audio/07 ड्रैकुला डर Pfähler.mp3" के साथ प्रयास किया और मुझे [2 एफ] [73] [7 9] [73] [74] [65] [6 डी] [2 एफ] [6d] [6e] [74] [2f] [75] [73] [62] [30] [2f] [61] [75] [64] [69] [6F] [2f] [30] [37 ] [20] [44] [72] [61] [63] [75] [6C] [61] [20] [44] [65] [72] [20] [50] [66] [इ 4] [ 68] [6C] [65] [72] [2 ई] [6d] [70] [33]। यह बहुत अजीब लगता है क्योंकि चरित्र एएससीआईआई सेट का हिस्सा है, और इसलिए यह ठीक होना चाहिए। क्या मै गलत हु? धन्यवाद! –

+0

@ लुका - हाँ, आप गलत हैं (क्षमा करें)। ASCII अंग्रेजी वर्ण (0x80 से कम) उनके यूटीएफ -8 समकक्षों के समान हैं। e ई 4 में परिवर्तित किया गया जो कानूनी यूटीएफ -8 नहीं है। –

+0

आह, मैं समझता हूँ! ठीक है, तो यूटीएफ -8 विस्तारित ASCII के साथ पिछड़ा संगत नहीं है। यह बताता है कि मैंने 'è' और 'ä' दोनों के साथ समस्या क्यों देखी। धन्यवाद! –

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