2010-07-08 8 views
11

मैं एक कोड स्निपेट पूछता हूं जो यूनिकोड टेक्स्ट को पिन करता है, पहले यूनिकोड टेक्स्ट में एक और यूनिकोड को जोड़ता है और नतीजा परिणाम देता है।मैं कुछ यूनिकोड टेक्स्ट को कैसे सिंक और कर सकता हूं?

पीएस यह कोड मुझे यूनिकोड के साथ एक और बड़ी समस्या हल करने में मदद करेगा। लेकिन इससे पहले कि मैं जो पूछूं वह पूरा करने के लिए महत्वपूर्ण बात है।

जोड़ा गया: जब मैं निष्पादन योग्य फ़ाइल चलाता हूं तो मैं किसी भी यूनिकोड प्रतीक को कमांड लाइन में लिख नहीं सकता। मुझे यह कैसे करना चाहिए?

+2

यूनिकोड पर्याप्त सटीक नहीं है। क्या आप यूटीएफ- [8/16/32] का उपयोग कर रहे हैं? क्या आप आंतरिक रूप से समान प्रतिनिधित्व का उपयोग करना चाहते हैं और जब इसे फ़ाइल में क्रमबद्ध किया जाता है? यदि आप प्रतिनिधित्वों को रूपांतरित करना चाहते हैं तो क्या आप इसे codecvt facet का उपयोग कर मैन्युअल रूप से या लोकेल के माध्यम से करना चाहते हैं? –

+0

जैसा आप चाहें !!! कोई फ़ाइल नहीं और कुछ और नहीं, और यह सब बताओ! – Narek

+0

इस विषय पर विभिन्न धागे पढ़ने के बाद, मेरा निष्कर्ष यह है कि सी ++ में करना असंभव है। ड्रॉप 'cin', 'cout' और C++ और C मानकों से बाकी सब कुछ और सादे विंडोज फ़ंक्शन' ReadConsoleW' और 'WriteConsoleW' का उपयोग करें। इस संबंध में सी और सी ++ मानकों को तोड़ दिया गया है। – Philipp

उत्तर

5

यहाँ एक उदाहरण है कि चार अलग अलग तरीकों, से पता चलता है, जिनमें से केवल तीसरी (सी conio) और चौथे (देशी विंडोज एपीआई) काम (पर केवल यदि stdin/stdout रीडायरेक्ट नहीं किया जाता) । ध्यान दें कि आपको अभी भी उस फ़ॉन्ट की आवश्यकता है जिसमें वह वर्ण शामिल है जिसे आप दिखाना चाहते हैं (लुसीडा कंसोल कम से कम ग्रीक और सिरिलिक का समर्थन करता है)। ध्यान दें कि यहां सब कुछ पूरी तरह से गैर पोर्टेबल है, टर्मिनल पर यूनिकोड स्ट्रिंग इनपुट/आउटपुट करने के लिए कोई पोर्टेबल तरीका नहीं है।

#ifndef UNICODE 
#define UNICODE 
#endif 

#ifndef _UNICODE 
#define _UNICODE 
#endif 

#define STRICT 
#define NOMINMAX 
#define WIN32_LEAN_AND_MEAN 

#include <iostream> 
#include <string> 
#include <cstdlib> 
#include <cstdio> 

#include <conio.h> 
#include <windows.h> 

void testIostream(); 
void testStdio(); 
void testConio(); 
void testWindows(); 

int wmain() { 
    testIostream(); 
    testStdio(); 
    testConio(); 
    testWindows(); 
    std::system("pause"); 
} 

void testIostream() { 
    std::wstring first, second; 
    std::getline(std::wcin, first); 
    if (!std::wcin.good()) return; 
    std::getline(std::wcin, second); 
    if (!std::wcin.good()) return; 
    std::wcout << first << second << std::endl; 
} 

void testStdio() { 
    wchar_t buffer[0x1000]; 
    if (!_getws_s(buffer)) return; 
    const std::wstring first = buffer; 
    if (!_getws_s(buffer)) return; 
    const std::wstring second = buffer; 
    const std::wstring result = first + second; 
    _putws(result.c_str()); 
} 

void testConio() { 
    wchar_t buffer[0x1000]; 
    std::size_t numRead = 0; 
    if (_cgetws_s(buffer, &numRead)) return; 
    const std::wstring first(buffer, numRead); 
    if (_cgetws_s(buffer, &numRead)) return; 
    const std::wstring second(buffer, numRead); 
    const std::wstring result = first + second + L'\n'; 
    _cputws(result.c_str()); 
} 

void testWindows() { 
    const HANDLE stdIn = GetStdHandle(STD_INPUT_HANDLE); 
    WCHAR buffer[0x1000]; 
    DWORD numRead = 0; 
    if (!ReadConsoleW(stdIn, buffer, sizeof buffer, &numRead, NULL)) return; 
    const std::wstring first(buffer, numRead - 2); 
    if (!ReadConsoleW(stdIn, buffer, sizeof buffer, &numRead, NULL)) return; 
    const std::wstring second(buffer, numRead); 
    const std::wstring result = first + second; 
    const HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE); 
    DWORD numWritten = 0; 
    WriteConsoleW(stdOut, result.c_str(), result.size(), &numWritten, NULL); 
} 
  • संपादित करें 1: मैं एक विधि conio के आधार पर जोड़ दिया है।
  • संपादित 2: मैं चारों ओर _O_U16TEXT साथ एक सा माइकल कापलान के ब्लॉग में वर्णित के रूप गड़बड़ है, लेकिन है कि प्रतीत होता है केवल था wgets (8 बिट) UTF-16 के रूप में ReadFile से डेटा की व्याख्या। मैं सप्ताहांत के दौरान थोड़ा और जांच करूँगा।
+0

धन्यवाद। कृपया मुझे बताएं कि यूनिकोड में कमांड लाइन में कैसे लिखना है? मैं नहीं कर सकता! यह लैटिन में अनदेखा करता है और लिखता है। – Narek

+0

इसके अलावा आप "wmain" के बजाय "मुख्य" लिखना चाहेंगे – Narek

+0

यदि आप कमांड लाइन तर्क पढ़ना चाहते हैं, तो 'wmain'' int wmain (int argc, wchar_t ** argv) 'के रूप में घोषित करें ('w' एक टाइपो नहीं है!) – Philipp

-1

यह ओएस पर निर्भर करता है। यदि आपका ओएस समझता है तो आप इसे यूटीएफ -8 अनुक्रम भेज सकते हैं।

+0

वह विंडोज पर है, जो यूटीएफ -16 का उपयोग करता है, लेकिन यूनिकोड टेक्स्ट के साथ काम करने के लिए विशेष एपीआई फ़ंक्शंस ('ReadConsole' /' WriteConsole') की आवश्यकता होती है। – Philipp

8

किस प्रकार यूनिकोड का मतलब है इसके आधार पर। मुझे लगता है कि आप का मतलब है कि आप अभी std::wstring के साथ काम कर रहे हैं। उस मामले में std::wcin और std::wcout का उपयोग करें।

इनकोडिंग आप Win32 के लिए की तरह अपने ओएस कार्यों का उपयोग कर सकते हैं के बीच रूपांतरण के लिए: या WideCharToMultiByte, MultiByteToWideChar आप वास्तविक पाठ है, तो आप की तरह libiconv

+1

यूटीएफ -8 के बजाय यूटीएफ -16 का उपयोग कर सकते हैं यदि आपका ओएस इसे समझता है। –

+0

+1: wchar_t (मुख्य रूप से विंडो के यूटीएफ -16) के लिए wstring के लिए wcout, चार के लिए स्ट्रिंग के लिए cout (डिफ़ॉल्ट रूप से लिनक्स, यूटीएफ -8) – rubenvb

+1

'wcin' और' wcout' विंडोज पर काम नहीं करते हैं। – Philipp

0

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

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

+2

विंडोज पर कोई स्थानीय एन्कोडिंग नहीं है और इस प्रकार विस्तृत धाराएं काम नहीं करती हैं। – Philipp

6

मुझे अतीत में एक ही समस्या थी, मेरे मामले मेंऔर sync_with_stdio चाल थी। इस प्रयास करें:

#include <iostream> 
#include <locale> 
#include <string> 

using namespace std; 

int main() { 
    ios_base::sync_with_stdio(false); 
    wcin.imbue(locale("en_US.UTF-8")); 
    wcout.imbue(locale("en_US.UTF-8")); 

    wstring s; 
    wstring t(L" la Polynésie française"); 

    wcin >> s; 
    wcout << s << t << endl; 
    return 0; 
} 
+1

इस कोड का परीक्षण करने के लिए? मुझे रनटाइम त्रुटि मिलती है! – Narek

+2

मैंने डीबग किया है, सीम इस समस्या है: wcin.imbue (लोकेल ("en_US.UTF-8")); – Narek

+1

@ नरेक हां, मैंने कोड का परीक्षण किया था। यह मेरे उबंटू पर बिना किसी समस्या के चलाता है। आपके पास कौन सी प्रणाली है? – Bolo

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

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