2009-09-03 18 views
18

मैं सी में एक छोटा सा एप्लीकेशन लिख रहा हूं जो एक साधारण पाठ फ़ाइल पढ़ता है और फिर लाइनों को एक-एक करके आउटपुट करता है। समस्या यह है कि पाठ फ़ाइल में विशेष वर्ण हैं जैसे Æ, Ø और Å दूसरों के बीच। जब मैं टर्मिनल में प्रोग्राम चलाता हूं तो उन अक्षरों के आउटपुट को "?" के साथ दर्शाया जाता है।सी (यूटीएफ -8 एन्कोडिंग) में विशेष वर्णों को संभालना

क्या कोई आसान फिक्स है?

उत्तर

28

सबसे पहली बात:

  1. पढ़ें बफर में
  2. libiconv उपयोग या UTF-8 से wchar_t प्रकार प्राप्त करने और इस तरह के wprintf()
  3. उपयोग के रूप में व्यापक चरित्र कार्यों से निपटने के उपयोग करने के लिए समान सी में व्यापक चरित्र कार्यों! अधिकांश फ़ाइल/आउटपुट हैंडलिंग फ़ंक्शंस में विस्तृत-वर्ण संस्करण

सुनिश्चित करें कि आपका टर्मिनल यूटीएफ -8 आउटपुट को संभाल सकता है। सही लोकेल सेटअप और लोकेल डेटा में हेरफेर करने से आपके लिए फ़ाइल खोलने और रूपांतरण के बहुत से स्वचालित हो सकते हैं ... आप जो कर रहे हैं उसके आधार पर।

याद रखें कि यूटीएफ -8 में कोड-पॉइंट या वर्ण की चौड़ाई परिवर्तनीय है। इसका मतलब है कि आप केवल बाइट की तलाश नहीं कर सकते हैं और ASCII के साथ पढ़ना शुरू कर सकते हैं ... क्योंकि आप कोड बिंदु के बीच में उतर सकते हैं। अच्छे पुस्तकालय कुछ मामलों में ऐसा कर सकते हैं।

यहाँ कुछ कोड (मेरा नहीं) कि UTF-8 फ़ाइल पढ़ने और विस्तृत चरित्र के कुछ उपयोग को दर्शाता है सी में से निपटने है

#include <stdio.h> 
#include <wchar.h> 
int main() 
{ 
    FILE *f = fopen("data.txt", "r, ccs=UTF-8"); 
    if (!f) 
     return 1; 

    for (wint_t c; (c = fgetwc(f)) != WEOF;) 
     printf("%04X\n", c); 

    fclose(f); 
    return 0; 
} 

लिंक

  1. libiconv
  2. Locale data in C/GNU libc
  3. Some handy info
  4. Another good Unicode/UTF-8 in C resource
+0

धन्यवाद दोस्त! मैं कोशिश करूँगा ... – o01

+0

कोई समस्या नहीं है। उस पर चिपकाएं, सी में यूनिकोड दुनिया में सबसे आसान चीज नहीं है ... मानकों से परिचित हो जाओ :) –

3

सुनिश्चित करें कि आप किसी भी बाइट को गलती से नहीं छोड़ रहे हैं; कुछ यूटीएफ -8 वर्ण लंबाई में एक से अधिक बाइट हैं (यह बिंदु की तरह है), और आपको उन्हें सभी रखने की आवश्यकता है।

यह हेक्स के रूप में बफर की सामग्री को मुद्रित करने के लिए उपयोगी हो सकता है, तो आप निरीक्षण कर सकते हैं जो बाइट्स वास्तव में पढ़ रहे हैं:

static void print_buffer(const char *buffer, size_t length) 
{ 
    size_t i; 

    for(i = 0; i < length; i++) 
    printf("%02x ", (unsigned int) buffer[i]); 
    putchar('\n'); 
} 

आप बस कुछ ही युक्त एक बहुत ही कम फ़ाइल लोड करने के बाद ऐसा कर सकते हैं, वर्ण।

यह भी सुनिश्चित करें कि टर्मिनल उचित एन्कोडिंग पर सेट है, इसलिए यह आपके पात्रों को यूटीएफ -8 के रूप में व्याख्या करता है।

+0

मेरा टर्मिनल यूटीएफ -8 एन्कोडिंग पर सेट है। कार्यक्रम टेक्स्ट फ़ाइल से प्रत्येक पंक्ति के सभी पात्रों को fgets() के माध्यम से एक char सरणी में संग्रहीत करता है; अगर मैं बाइट खो रहा हूं, तो मुझे नहीं पता कि इसे क्यों या कैसे ठीक किया जाए ... (बस सी बीटीडब्ल्यू सीखना शुरू करें) – o01

+0

@ ईरिक, fgets() का उपयोग न करें जो ASCII उन्मुख है। मेरी पोस्ट से fgetwc() का प्रयोग करें। –

2

शायद अपनी पाठ फ़ाइल आईएसओ 8559-1 इनकोडिंग है, लेकिन अपने टर्मिनल UTF-8 है। बाइट-ओरिएंटेड टेक्स्ट हैंडलिंग से निपटने के दौरान इस प्रकार का विसंगति एक मानक समस्या है; अन्य सी प्रोग्राम (जैसे कि मानक 'बिल्ली' और 'अधिक' कमांड) वही काम करेंगे और इसे आमतौर पर एक त्रुटि या कुछ नहीं माना जाता है जिसे ठीक करने की आवश्यकता होती है।

यदि आप ठीक से बाइट्स के बजाय यूनिकोड वर्ण स्तर पर काम करना चाहते हैं, लेकिन आपको अपने प्रोग्राम के चारों ओर अपने चरित्र प्रकार के रूप में wchar का उपयोग करने की आवश्यकता होगी, और आने वाले उपयोगकर्ता को यह निर्दिष्ट करने के लिए स्विच प्रदान करना होगा फ़ाइल एन्कोडिंग वास्तव में है। (हालांकि यह अनुमान लगाने के लिए कभी-कभी संभव होता है, यह बहुत विश्वसनीय नहीं है।)

2

मुझे नहीं पता कि यह मदद कर सकता है लेकिन यदि आप सुनिश्चित हैं कि टर्मिनल और इनपुट फ़ाइल के एन्कोडिंग समान हैं, तो आप कोशिश कर सकते हैं setlocale():

#include <locale.h> 
… 
setlocale(LC_CTYPE, ""); 
+0

मैंने 'सेटलोकेल (एलसी_सीटीपीई, "यूटीएफ -8") का उपयोग किया; '। सफलता के साथ फ़ाइल को पढ़ने के लिए आवश्यक था हालांकि खोल वातावरण ठीक से कॉन्फ़िगर किया गया था। – lkuty

+0

'setlocale (LC_CTYPE," ") 'के साथ, लोकेल का प्रत्येक भाग जिसे संशोधित किया जाना चाहिए पर्यावरण चर के अनुसार सेट किया गया है। – jgrocha

+0

ओह हाँ, क्षमा करें, यह '' "और' न्यूल 'होना चाहिए था। –

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