2013-11-25 11 views
5

मैं कुछ चीनी वेब फ़ाइलों को लाने के लिए एक वेब क्रॉलर लिख रहा हूं। Fetched फ़ाइलें utf-8 में एन्कोड किए गए हैं। और मुझे उन फाइलों को कुछ पार्स करने के लिए पढ़ने की जरूरत है, जैसे यूआरएल और चीनी अक्षरों को निकालना। लेकिन मैंने पाया कि जब मैं एक std :: स्ट्रिंग चर में फ़ाइल पढ़ता हूं और इसे कंसोल में आउटपुट करता हूं, तो चीनी वर्ण कचरे के पात्र बन जाते हैं। मैंने boost :: regex को std :: स्ट्रिंग वेरिएबल में लागू किया है और सभी यूआरएल लेकिन चीनी वर्ण निकाल सकते हैं।चीनी वर्ण वाले यूटीएफ -8 एन्कोडेड फ़ाइल को कैसे पढ़ा जाए और उन्हें कंसोल पर सही तरीके से आउटपुट करें?

मैं उन समस्याओं को कैसे हल कर सकता हूं?

पीएस मेरी सीपीपी फाइलें डिफ़ॉल्ट रूप से एएनएसआई के रूप में एन्कोड की जाती हैं, ऑपरेटिंग सिस्टम चीनी भाषा में विन 8 है;

+0

लगता है जैसे आपको यूटीएफ -8 से 'कोड पेज' बदलने की ज़रूरत है, जो कि आपके कंसोल चीनी वर्णों के लिए जो भी कोड पेज उपयोग करता है। यूटीएफ -8 से यूनिकोड में बदलने के लिए मल्टीबाइट टॉवाइड चेयर को कॉल करें, इसके बाद वाइडरहटोमल्टी बाइट यूनिकोड से अपने स्थानीय कोड पेज में बदलने के लिए। – john

+0

शायद कंसोल की गलती शायद। फ़ाइल में '>' 'आईएनजी आज़माएं। यदि यह चीनी वर्णों के साथ वैध यूटीएफ -8 साबित हुआ है, तो आपका प्रोग्राम ठीक काम कर रहा है और यह एक विंडोज़ प्रश्न है। (बेशक, आपको अभी भी अपने प्रोग्राम को विंडोज के आसपास काम करने की आवश्यकता हो सकती है, लेकिन आपको पता चलेगा कि कौन गलती है।) – aib

+0

@ एआईबी हां, जब मैं std :: स्ट्रिंग चर को दूसरी फ़ाइल में रीडायरेक्ट करता हूं, तो सामग्री अभी भी मान्य है Chiese पात्रों के साथ यूटीएफ -8। मेरा कंसोल का कोड पेज '936 है (एएनएसआई/OEM - 简体 中文 जीबीके)" '। –

उत्तर

7

यह कोड सहायता कर सकता है (इसे वीसी ++ 2010 के साथ संकलित किया गया था)। मैंने इसे गैर-लैटिन वर्ण वाले यूटीएफ -8 फ़ाइल के साथ परीक्षण किया और ऐसा लगता है कि यह काम करता है, लेकिन मुझे नहीं पता कि यह चीनी पात्रों के साथ ठीक काम करेगा या नहीं। अधिक जानकारी के लिए निम्न लिंक देखें: _setmode और codecvt_utf8

#include <iostream> 
#include <fstream> 
#include <string> 
#include <locale> 
#include <codecvt> 
#include <fcntl.h> 
#include <io.h> 

using namespace std; // Sorry for this! 

void read_all_lines(const wchar_t *filename) 
{ 
    wifstream wifs; 
    wstring txtline; 
    int c = 0; 

    wifs.open(filename); 
    if(!wifs.is_open()) 
    { 
     wcerr << L"Unable to open file" << endl; 
     return; 
    } 
    // We are going to read an UTF-8 file 
    wifs.imbue(locale(wifs.getloc(), new codecvt_utf8<wchar_t, 0x10ffff, consume_header>())); 
    while(getline(wifs, txtline)) 
     wcout << ++c << L'\t' << txtline << L'\n'; 
    wcout << endl; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    // Console output will be UTF-16 characters 
    _setmode(_fileno(stdout), _O_U16TEXT); 
    if(argc < 2) 
    { 
     wcerr << L"Filename expected!" << endl; 
     return 1; 
    } 
    read_all_lines(argv[1]); 
    return 0; 
} 

हैं चीनी अक्षरों के रूप में उम्मीद मत देखो, सुनिश्चित करें कि कंसोल का समर्थन करता है कि एक फ़ॉन्ट उपयोग कर रहा है UTF-16 (यानी। बिटमैप फ़ॉन्ट का उपयोग न करें)।

+1

क्या आपका समाधान अन्य प्लेटफॉर्म या विंडोज के तहत केवल वीसी में काम करता है? –

1

सामान्य में,, w वेरिएंट, (wstring, wfstream, wcout) का उपयोग, आवश्यकताओं से मेल करने के लिए अपने स्थान सेट स्ट्रिंग शाब्दिक के मोर्चे पर एक L लटका। locale::global(locale("")) पर्यावरण डिफ़ॉल्ट से मेल खाने के लिए सेट अप करता है, फिर प्रत्येक स्ट्रीम पर जो उस डिफ़ॉल्ट के अनुसार नहीं चल रहा है उदा। आपके टर्मिनल की लोकेल सेटिंग्स के लिए wcout.imbue(locale("Chinese_China.936"))might be Microsoft's name। जो भी मैं चाहता हूं वह हमेशा करने के लिए पर्याप्त रहा है, उम्मीद है कि यह आपके लिए भी काम करेगा।

#include <iostream> 
#include <locale> 
using namespace std; 
int main() { 
    locale::global(locale("")); 
    wstring word; 
    while (wcin >>word) 
    wcout<<word<<'\n'; 
    wcout<<L"好運n"; 
} 
0

यदि आपको वर्णों को सही तरीके से प्रदर्शित करने की आवश्यकता है, तो आप जीएनयू से libiconv का उपयोग कर सकते हैं। यदि आपको केवल urls को संसाधित करने की आवश्यकता है, तो std :: string ठीक काम करता है। समस्या विंडोज कंसोल का कोड पेज है, न कि स्ट्रिंग स्वयं। लोकेल का उपयोग ओएस और stdC++ lib के कार्यान्वयन पर निर्भर करता है, इसलिए मैं उपयोग करने के लिए प्रोत्साहित नहीं करता हूं।

विंडो की मल्टीबाइट टोवाइडर सहायता कर सकती है, लेकिन आपको स्ट्रिंग पर रूपांतरण करने के तरीके पर एमएस के विनिर्देशों की जांच करने की आवश्यकता है।

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