std :: wstring VS std :: স্ট্রিং


740

আমি std::stringএবং এর মধ্যে পার্থক্য বুঝতে সক্ষম নই std::wstring। আমি জানি wstringইউনিকোড অক্ষরের মতো বিস্তৃত অক্ষরকে সমর্থন করে। আমি নিম্নলিখিত প্রশ্ন পেয়েছি:

  1. যখন আমি ব্যবহার করা উচিত std::wstringউপর std::string?
  2. std::stringবিশেষ অক্ষরগুলি সহ পুরো ASCII অক্ষর সেটটি ধরে রাখতে পারে ?
  3. হয় std::wstringসব জনপ্রিয় সি ++ কম্পাইলার দ্বারা সমর্থিত?
  4. বিস্তৃত চরিত্র ’ আসলে কী?

10
এএসসিআইআই চর্যাচটার সেটে প্রচুর "বিশেষ" অক্ষর নেই, সর্বাধিক বহিরাগত সম্ভবত `(ব্যাককোট)। স্ট্যান্ড :: স্ট্রিং সমস্ত ইউনিকোড অক্ষর (সাধারণত, 8 বিট চর) এর প্রায় 0.025% ধরে রাখতে পারে
এমএসএলটাররা

3
বিস্তৃত অক্ষর এবং কোন ধরণের ব্যবহার করতে হবে সে সম্পর্কে ভাল তথ্য এখানে পাওয়া যাবে: প্রোগ্রামার্স.স্ট্যাকেক্সেঞ্জার
কুইকশানগুলি ১০০২২০৫/২

14
ঠিক আছে, এবং যেহেতু আমরা 2012 সালে আছি , utf8e Everybody.org লেখা ছিল। এটি অধিকার এবং সি ++ / উইন্ডোজের সাথে ভুলগুলি সম্পর্কে সমস্ত প্রশ্নের উত্তর দেয়।
পাভেল রদজিভিলভস্কি

42
@ এসএমএল্টারস: স্টাডি :: স্ট্রিংটি ইউনিকোডের সমস্ত অক্ষরের 100% ধারণ করতে পারে, যদিও CHAR_BIT 8 হয় এটি স্ট্যান্ড :: স্ট্রিংয়ের এনকোডিংয়ের উপর নির্ভর করে, যা সিস্টেমের স্তরে UTF-8 হতে পারে (উইন্ডো ব্যতীত প্রায় সর্বত্র ) বা আপনার অ্যাপ্লিকেশন স্তরে। নেটিভ সরু এনকোডিং ইউনিকোড সমর্থন করে না? কোনও সমস্যা নেই, কেবল এটি ব্যবহার করবেন না, পরিবর্তে ইউটিএফ -8 ব্যবহার করুন।
ইয়াকভ গালকা

8
এই বিষয়ে দুর্দান্ত পঠন: utf8everywhere.org
টিমোথি শিল্ডস

উত্তর:


989

string? wstring?

std::stringএকটি হয় basic_stringএকটি উপর টেমপ্লেট করা char, এবং std::wstringএকটি উপর wchar_t

char বনাম wchar_t

charএকটি চরিত্র, সাধারণত একটি 8-বিট চরিত্র ধারণ করার কথা।
wchar_tধারণা করা হয় একটি বিস্তৃত চরিত্র রয়েছে, এবং তারপরে, জিনিসগুলি জটিল হয়ে উঠবে:
লিনাক্স-এ, wchar_t4 বাইট, উইন্ডোতে, এটি 2 বাইট হয়।

তাহলে ইউনিকোডের কী হবে ?

সমস্যাটি হ'ল উভয়ই সরাসরি ইউনিকোডের সাথে আবদ্ধ charনয় wchar_t

লিনাক্সে?

একটি লিনাক্স ওএস নেওয়া যাক: আমার উবুন্টু সিস্টেমটি ইতিমধ্যে ইউনিকোড সচেতন। যখন আমি একটি চর স্ট্রিংয়ের সাথে কাজ করি, তখন এটি স্থানীয়ভাবে ইউটিএফ -8 (যেমন অক্ষরের ইউনিকোড স্ট্রিং) এ এনকোড থাকে । নিম্নলিখিত কোড:

#include <cstring>
#include <iostream>

int main(int argc, char* argv[])
{
   const char text[] = "olé" ;


   std::cout << "sizeof(char)    : " << sizeof(char) << std::endl ;
   std::cout << "text            : " << text << std::endl ;
   std::cout << "sizeof(text)    : " << sizeof(text) << std::endl ;
   std::cout << "strlen(text)    : " << strlen(text) << std::endl ;

   std::cout << "text(ordinals)  :" ;

   for(size_t i = 0, iMax = strlen(text); i < iMax; ++i)
   {
      std::cout << " " << static_cast<unsigned int>(
                              static_cast<unsigned char>(text[i])
                          );
   }

   std::cout << std::endl << std::endl ;

   // - - - 

   const wchar_t wtext[] = L"olé" ;

   std::cout << "sizeof(wchar_t) : " << sizeof(wchar_t) << std::endl ;
   //std::cout << "wtext           : " << wtext << std::endl ; <- error
   std::cout << "wtext           : UNABLE TO CONVERT NATIVELY." << std::endl ;
   std::wcout << L"wtext           : " << wtext << std::endl;

   std::cout << "sizeof(wtext)   : " << sizeof(wtext) << std::endl ;
   std::cout << "wcslen(wtext)   : " << wcslen(wtext) << std::endl ;

   std::cout << "wtext(ordinals) :" ;

   for(size_t i = 0, iMax = wcslen(wtext); i < iMax; ++i)
   {
      std::cout << " " << static_cast<unsigned int>(
                              static_cast<unsigned short>(wtext[i])
                              );
   }

   std::cout << std::endl << std::endl ;

   return 0;
}

নিম্নলিখিত পাঠ্য আউটপুট দেয়:

sizeof(char)    : 1
text            : olé
sizeof(text)    : 5
strlen(text)    : 4
text(ordinals)  : 111 108 195 169

sizeof(wchar_t) : 4
wtext           : UNABLE TO CONVERT NATIVELY.
wtext           : ol�
sizeof(wtext)   : 16
wcslen(wtext)   : 3
wtext(ordinals) : 111 108 233

আপনি দেখতে পাবেন "ওল" পাঠ্যটি charসত্যই চারটি চর দ্বারা নির্মিত: 110, 108, 195 এবং 169 (পিছনের শূন্যটি গণনা করছে না)। (আমি আপনাকে wchar_tএকটি অনুশীলন হিসাবে কোডটি অধ্যয়ন করতে দেব )

সুতরাং, charলিনাক্সে কোনও কাজ করার সময় , আপনি সাধারণত অজান্তেই ইউনিকোড ব্যবহার করে শেষ হওয়া উচিত। এবং যেমন std::stringকাজ করে charতেমনি std::stringইউনিকোড-প্রস্তুত।

নোট করুন std::string, সি স্ট্রিং এপিআইয়ের মতো, "অল" স্ট্রিংটি তিনটি নয়, 4 টি অক্ষর হিসাবে বিবেচনা করবে। সুতরাং ইউনিকোড অক্ষরের সাথে কাটা / খেলার সময় আপনার সতর্ক হওয়া উচিত কারণ ইউটিএফ -8 এ কিছু অক্ষরের মিশ্রণ নিষিদ্ধ।

উইন্ডোজে?

উইন্ডোজে এটি কিছুটা আলাদা। উইন 32 কে ইউনিকোডের আগমনের আগে, সমস্ত বিশ্বের উত্পাদিত charবিভিন্ন চরসেট / কোডপেজের সাথে এবং এর সাথে কাজ করার জন্য প্রচুর অ্যাপ্লিকেশন সমর্থন করতে হয়েছিল ।

সুতরাং তাদের সমাধানটি একটি আকর্ষণীয় সমাধান ছিল: যদি কোনও অ্যাপ্লিকেশন এর সাথে কাজ করে char, তবে মেশিনে স্থানীয় চরসেট / কোডপেজ ব্যবহার করে চার স্ট্রিংগুলি জিইউআই লেবেলে এনকোডড / মুদ্রিত / দেখানো হবে। উদাহরণস্বরূপ, ফরাসি-স্থানীয়করণযুক্ত উইন্ডোতে "ওল" হ'ল "ওল", তবে সিরিলিক-স্থানীয়ীকৃত উইন্ডোজ ("যদি আপনি উইন্ডোজ -1211 ব্যবহার করেন তবে" ওলি ) কিছু আলাদা হবে । সুতরাং, "historicalতিহাসিক অ্যাপ্লিকেশনগুলি" এখনও একই পুরানো পথে কাজ করবে।

ইউনিকোড ভিত্তিক অ্যাপ্লিকেশনগুলির জন্য, উইন্ডোজ ব্যবহার করে wchar_t, যা 2-বাইট প্রশস্ত, এবং ইউটিএফ -16 এ এনকোড থাকে , যা ইউনিকোড 2-বাইট অক্ষরগুলিতে এনকোড থাকে (বা খুব কমপক্ষে, বেশিরভাগই সুসংগত ইউসিএস -২, যা প্রায় একই জিনিস আইআইআরসি)।

ব্যবহার অ্যাপ্লিকেশন charবলা হয় "multibyte" (কারণ প্রতিটি গ্লিফের এক বা একাধিক গঠিত হয় char, গুলি) ব্যবহার করার সময় অ্যাপ্লিকেশন wchar_tবলা হয় "widechar" (কারণ প্রতিটি গ্লিফের এক বা দুই গঠিত হয় wchar_t। দেখুন MultiByteToWideChar এবং WideCharToMultiByte আরও তথ্যের জন্য Win32 রূপান্তর API- টি।

সুতরাং, আপনি যদি উইন্ডোজে কাজ করেন তবে আপনি খারাপভাবে ব্যবহার করতে চানwchar_t (আপনি যদি জিটিকে + বা কিউটি ... এর মতো লুকানো ফ্রেমওয়ার্ক ব্যবহার না করেন )। আসল বিষয়টি হ'ল পর্দার আড়ালে উইন্ডোজ wchar_tস্ট্রিংয়ের সাথে কাজ করে, তাই এমনকি historicalতিহাসিক অ্যাপ্লিকেশনগুলির এপিআই ব্যবহার করার সময় (উইন 32 জিইউআইতে লেবেল সেট করতে নিম্ন স্তরের এপিআই ফাংশন) তাদের charস্ট্রিং রূপান্তরিত হবে convertedwchar_tSetWindowText()

স্মৃতি সমস্যা?

ইউটিএফ -32 অক্ষর প্রতি 4 বাইট, তাই যুক্ত করার মতো খুব বেশি কিছুই নেই, কেবলমাত্র যদি কোনও ইউটিএফ -8 পাঠ্য এবং ইউটিএফ -16 পাঠ্য সর্বদা একটি ইউটিএফ -32 পাঠ্যের চেয়ে কম বা একই পরিমাণ মেমরি ব্যবহার করে (এবং সাধারণত কম )।

যদি কোনও মেমরির সমস্যা থাকে তবে বেশিরভাগ পশ্চিমা ভাষার চেয়ে আপনার জানা উচিত, ইউটিএফ -8 পাঠ্যটি একই ইউটিএফ -১ one এর চেয়ে কম মেমরি ব্যবহার করবে।

তবুও, অন্যান্য ভাষার জন্য (চাইনিজ, জাপানি ইত্যাদি) ব্যবহৃত মেমরিটি ইউটিএফ -8 এর তুলনায় ইউটিএফ -8 এর চেয়ে একরকম বা কিছুটা বড় হবে।

সব মিলিয়ে, ইউটিএফ -16 বেশিরভাগ অক্ষর প্রতি 2 এবং ঘটনাক্রমে 4 বাইট ব্যবহার করবে (যদি না আপনি কোনও রকম রহস্যময় ভাষার গিলিফগুলি (ক্লিংন? এলভিশ?) ব্যবহার করছেন, তবে ইউটিএফ -8 1 থেকে 4 বাইট ব্যয় করবে)।

আরও তথ্যের জন্য http://en.wikedia.org/wiki/UTF-8#Compare_to_UTF-16 দেখুন ।

উপসংহার

  1. যখন আমার স্টাড :: স্ট্রিং ওভার স্ট্রিং :: স্ট্রিং ব্যবহার করা উচিত?

    লিনাক্সে? প্রায় না (§).
    উইন্ডোজে? প্রায় সবসময় (§).
    ক্রস প্ল্যাটফর্ম কোডে? আপনার টুলকিট উপর নির্ভর করে ...

    (§): আপনি অন্যথায় বলার মতো কোনও সরঞ্জামকিট / ফ্রেমওয়ার্ক ব্যবহার না করে

  2. std::stringবিশেষ অক্ষর সহ সমস্ত ASCII চরিত্র সেটটি ধরে রাখতে পারে?

    বিজ্ঞপ্তি: std::stringএকটি 'বাইনারি' বাফার ধরে রাখার জন্য উপযুক্ত, যেখানে একটি std::wstringনেই!

    লিনাক্সে? হ্যাঁ.
    উইন্ডোজে? উইন্ডোজ ব্যবহারকারীর বর্তমান লোকেলের জন্য কেবলমাত্র বিশেষ অক্ষর উপলব্ধ।

    সম্পাদনা ( জোহান জেরেলের একটি মন্তব্যের পরে ):
    একটি std::stringসমস্ত- charভিত্তিক স্ট্রিংগুলি হ্যান্ডেল করার জন্য যথেষ্ট হবে (প্রত্যেকটি char0 থেকে 255 পর্যন্ত একটি সংখ্যা)। কিন্তু:

    1. ASCII 0 থেকে 127 যাওয়ার কথা charরয়েছে। উচ্চতরগুলি ASCII নয়।
    2. char0 থেকে 127 পর্যন্ত একটি সঠিকভাবে অনুষ্ঠিত হবে
    3. একটি char128 থেকে 255 আপনার এনকোডিং (ইউনিকোড, অ-ইউনিকোড, ইত্যাদি) উপর নির্ভর করে একটি গুরূত্ব থাকবে, কিন্তু এটা হিসাবে তারা হল UTF-8 এনকোড করা হয় যতদিন সব ইউনিকোড গ্লিফ রাখা সক্ষম হবে।
  3. হয় std::wstringপ্রায় সব জনপ্রিয় সি ++ কম্পাইলার দ্বারা সমর্থিত?

    বেশিরভাগ ক্ষেত্রে, উইন্ডোতে পোর্ট করা জিসিসি ভিত্তিক সংকলক ব্যতীত।
    এটি আমার জি ++ ৪.৩.২ (লিনাক্সের অধীনে) কাজ করে এবং আমি ভিজ্যুয়াল সি ++ 6 সাল থেকে উইন 32 এ ইউনিকোড এপিআই ব্যবহার করেছি।

  4. বিস্তৃত চরিত্রটি আসলে কী?

    সি / সি ++ এ, এটি একটি অক্ষর টাইপ লিখিত wchar_tযা সাধারণ charঅক্ষরের ধরণের চেয়ে বড় is এটি এমন অক্ষরের ভিতরে রাখতে ব্যবহার করা হবে যার সূচিগুলি (ইউনিকোড গ্লাইফগুলি) 255 (বা 127, নির্ভর করে ...) এর চেয়ে বড়।


4
@ অদ্ভুত: সম্ভবত ডাব্লুচার_টি ইউটিএফ -১ of এর আবির্ভাবের আগে সমস্ত ইউসিএস -২ চরগুলি (বেশিরভাগ ইউটিএফ -১ cha অক্ষর) পরিচালনা করার জন্য যথেষ্ট বলে মনে করা হয়েছিল ... অথবা মাইক্রোসফ্টের পিসিক্স ছাড়া অন্য অগ্রাধিকার ছিল যেমন ইউনিকোডে সহজে অ্যাক্সেস দেওয়ার মতো উইন 32 এ চরের কোডেপেজড ব্যবহারটি পরিবর্তন না করে।
প্যারাসেবল

4
@ সোরিন সারবারিয়া: ইউটিএফ -8 ১--6 বাইট নিতে পারে, তবে দৃশ্যত স্ট্যান্ডার্ডটি এটি 1-4-এ সীমাবদ্ধ করে। আরও তথ্যের জন্য en.wikedia.org/wiki/UTF8# বিবরণ দেখুন ।
পেরেেসবাল

8
যদিও এই উদাহরণগুলি লিনাক্স এবং উইন্ডোজে বিভিন্ন ফলাফল দেয় তবে সি ++ প্রোগ্রামে olèইউটিএফ -8 হিসাবে এনকোড করা আছে কিনা তা বাস্তবায়ন-কার্য-বিহীন আচরণ রয়েছে । আরও, কারণ আপনি করতে পারবেন না নেটিভ স্ট্রিম wchar_t *করার std::coutকারণ ধরনের একটি মন্দ গঠিত প্রোগ্রাম ফলে বেমানান এবং এটি এনকোডিং ব্যবহার কিছুই করার আছে। এটি উল্লেখ করার মতো যে আপনি প্ল্যাটফর্মের চেয়ে নিজের এনকোডিং পছন্দটি ব্যবহার করেন std::stringবা std::wstringনির্ভর করেন, বিশেষত যদি আপনি চান যে আপনার কোডটি পোর্টেবল হতে পারে।
জন লিডেগ্রেন

14
উইন্ডোজ আসলে ইউটিএফ -16 ব্যবহার করে এবং বেশ কিছু সময়ের জন্য ছিল, উইন্ডোজের পুরানো সংস্করণগুলি ইউসিএস -2 ব্যবহার করে তবে এটি আর হয় না। আমার একমাত্র ইস্যুটি এই উপসংহারটি যা std::wstringউইন্ডোজে ব্যবহার করা উচিত কারণ এটি ইউনিকোড উইন্ডোজ এপিআইয়ের জন্য আরও ভাল ফিট যা আমি মনে করি এটি মিথ্যাবাদী। যদি আপনার একমাত্র উদ্বেগটি ইউনিকোড উইন্ডোজ এপিআইতে কল করে এবং স্ট্রিংগুলিকে মার্শালিং না করে তবে অবশ্যই নিশ্চিত তবে আমি এটি সাধারণ ক্ষেত্রে হিসাবে কিনছি না।
জন লিডেগ্রেন

15
@ জন লেডেগ্রেন:: If your only concern was calling into the Unicode Windows API and not marshalling strings then sureতাহলে, আমরা সম্মত হই। আমি জাভাস্ক্রিপ্ট নয়, সি ++ এ কোডিং করছি। সংকলনের সময় এটি করা যেতে পারে যখন রানটাইমের সময় অকেজো মার্শেলিং বা অন্য কোনও সম্ভাব্য ব্যয়বহুল প্রক্রিয়াকরণ এড়িয়ে চলা সেই ভাষার কেন্দ্রে রয়েছে। উইনএপিআইয়ের বিরুদ্ধে কোডিং করা এবং ব্যবহার std::stringকরা রানটাইম রিসোর্সগুলির কেবল একটি অযৌক্তিক অপচয় is আপনি এটিকে অবাস্তব মনে করেন এবং এটি ঠিক আপনার মতামত হিসাবে ঠিক আছে। আমার নিজস্বটি হ'ল আমি লিনাক্স দিক থেকে আরও ভাল দেখায় কারণ আমি উইন্ডোজে হতাশার সাথে কোড লিখব না।
প্যার্সেবল

71

আমি std::wstringইন্টারফেসের প্রয়োজন অনুসারে বা উইন্ডোজ এপিআই কলগুলির নিকটবর্তী কোথাও এবং সিন্ট্যাকটিক চিনির হিসাবে সংশ্লিষ্ট এনকোডিং রূপান্তরগুলি বাদ দিয়ে উইন্ডোজ বা অন্য কোথাও এড়ানো পরামর্শ দিই ।

আমার মতামতটির সংক্ষিপ্ত বিবরণ http://utf8everywhere.org এ দেওয়া হয়েছে যার মধ্যে আমি সহ-লেখক।

আপনার অ্যাপ্লিকেশনটি API- কল-কেন্দ্রিক না হওয়া পর্যন্ত, যেমন প্রধানত ইউআই অ্যাপ্লিকেশন, ইউনিকোড স্ট্রিংগুলি স্টাড :: স্ট্রিংয়ে সংরক্ষণ এবং ইউটিএফ -8 এ এনকোড করা, API কলগুলির নিকটে রূপান্তর সম্পাদন করার পরামর্শ দেওয়া হয়। নিবন্ধে বর্ণিত সুবিধাগুলি রূপান্তরগুলির আপত্তিজনক বিরক্তি, বিশেষত জটিল অ্যাপ্লিকেশনগুলিতে বেশি। এটি বহু-প্ল্যাটফর্ম এবং গ্রন্থাগারের উন্নয়নের জন্য দ্বিগুণ।

এবং এখন, আপনার প্রশ্নের উত্তর:

  1. কয়েকটি দুর্বল কারণ। এটি historicalতিহাসিক কারণে বিদ্যমান, যেখানে উইডিকাররা ইউনিকোডকে সমর্থন করার উপযুক্ত উপায় বলে মনে করা হয়েছিল। এটি এখন ইউটিএফ -16 স্ট্রিং পছন্দ করে এমন API গুলি ইন্টারফেস করতে ব্যবহৃত হয়। আমি এগুলিকে কেবল এপিআই কলগুলির প্রত্যক্ষ আশেপাশে ব্যবহার করি।
  2. এটি স্ট্যান্ড :: স্ট্রিংয়ের সাথে কোনও সম্পর্ক রাখে না। আপনি এতে যে কোনও এনকোডিং রেখেছেন তা এটি ধরে রাখতে পারে। একমাত্র প্রশ্ন হ'ল আপনি কীভাবে এর বিষয়বস্তুটি ব্যবহার করেন। আমার প্রস্তাবটি ইউটিএফ -8, সুতরাং এটি সমস্ত ইউনিকোড অক্ষর সঠিকভাবে ধরে রাখতে সক্ষম হবে। এটি লিনাক্সের একটি সাধারণ অনুশীলন, তবে আমি মনে করি উইন্ডোজ প্রোগ্রামগুলিও এটি করা উচিত।
  3. না।
  4. প্রশস্ত চরিত্র একটি বিভ্রান্তিকর নাম। ইউনিকোডের প্রথম দিনগুলিতে একটি বিশ্বাস ছিল যে একটি চরিত্র দুটি বাইটে এনকোড করা যায়, তাই নামটি। আজ, এটি "চরিত্রের যে কোনও অংশ যা দুটি বাইট দীর্ঘ।" ইউটিএফ -16 এই জাতীয় বাইট জোড়া (ওরফে ওয়াইড অক্ষর) এর ক্রম হিসাবে দেখা হয়। ইউটিএফ -16 এর একটি অক্ষর এক বা দুটি জোড়া লাগে।

37

সুতরাং, এখন এখানে প্রতিটি পাঠকের তথ্য, পরিস্থিতি সম্পর্কে পরিষ্কার ধারণা থাকা উচিত। যদি তা না হয় তবে অবশ্যই আপনাকে পেরেেসবালের অসামান্য বিস্তৃত উত্তর পড়তে হবে [ বিটিডাব্লু : ধন্যবাদ!]।

আমার ব্যবহারিক উপসংহারটি মারাত্মকভাবে সহজ: সমস্ত সি ++ (এবং এসটিএল) "চরিত্রের এনকোডিং" স্টাফগুলি যথেষ্ট ভাঙ্গা এবং অকেজো। মাইক্রোসফ্টকে দোষ দিন বা না করুন, এটি কোনওভাবেই সহায়তা করবে না।

আমার সমাধান, গভীরতর তদন্তের পরে, অনেক হতাশা এবং ফলস্বরূপ অভিজ্ঞতাগুলি নিম্নলিখিত:

  1. স্বীকার করুন, এনকোডিং এবং রূপান্তরকরণের জন্য আপনাকে নিজেরাই দায়বদ্ধ হতে হবে (এবং আপনি দেখতে পাবেন যে এর অনেক কিছুই তুচ্ছ)

  2. যে কোনও ইউটিএফ -8 এনকোডযুক্ত স্ট্রিংয়ের জন্য std :: স্ট্রিং ব্যবহার করুন (মাত্র একটি typedef std::string UTF8String)

  3. গ্রহণ করুন যে এই জাতীয় UTF8 স্ট্রিং অবজেক্টটি কেবল বোবা, তবে সস্তা ধারক। এর মধ্যে অক্ষরগুলিকে কখনও অ্যাক্সেস এবং / অথবা হেরফের করবেন না (কোনও অনুসন্ধান, প্রতিস্থাপন এবং এ জাতীয় কিছু নয়)। আপনি করতে পারেন, কিন্তু আপনি সত্যিই সত্যিই, সত্যিই মাল্টি-বাইট স্ট্রিংয়ের জন্য টেক্সট ম্যানিপুলেশন অ্যালগরিদমগুলি আপনার সময় নষ্ট করতে চান না! এমনকি যদি অন্য লোকেরা ইতিমধ্যে এমন মূর্খ কাজগুলি করে, তা করবেন না! এটা হতে দাও! (ঠিক আছে, এমন পরিস্থিতিতে রয়েছে যেখানে এটি বোধগম্য হয় ... কেবল তাদের জন্য আইসিইউ লাইব্রেরি ব্যবহার করুন)।

  4. ইউসিএস -২ এনকোডেড স্ট্রিংগুলির জন্য স্টাডি :: wstring ব্যবহার করুন typedef std::wstring UCS2String- এটি একটি আপস, এবং ডাব্লু উইন 32 এপিআই চালু করেছে এমন গণ্ডগোলের জন্য ছাড়)। ইউসিএস -২ আমাদের বেশিরভাগের জন্যই যথেষ্ট (পরে আরও ...)।

  5. যখনই কোনও অক্ষর দ্বারা অক্ষর অ্যাক্সেসের প্রয়োজন হয় তখন ইউসিএস 2 স্ট্রিং উদাহরণগুলি ব্যবহার করুন (পড়ুন, ম্যানিপুলেট করুন এবং আরও কিছু)। কোনও অক্ষর-ভিত্তিক প্রক্রিয়াকরণ কোনও নন-মাল্টবাইট-উপস্থাপনায় করা উচিত। এটি সহজ, দ্রুত, সহজ।

  6. ইউটিএফ -8 এবং ইউসিএস -2 এর মধ্যে পিছনে রূপান্তর করতে দুটি ইউটিলিটি ফাংশন যুক্ত করুন:

    UCS2String ConvertToUCS2( const UTF8String &str );
    UTF8String ConvertToUTF8( const UCS2String &str );

রূপান্তরগুলি সোজা, Google এর এখানে সহায়তা করা উচিত ...

এটাই. ইউটিএফ 8 স্ট্রিং ব্যবহার করুন যেখানেই মেমরিটি মূল্যবান এবং সমস্ত ইউটিএফ -8 আই / ও। স্ট্রিংটি বিশ্লেষণ এবং / অথবা ম্যানিপুলেট করতে হবে যেখানেই ইউসিএস 2 স্ট্রিং ব্যবহার করুন। আপনি যে কোনও সময় এই দুটি উপস্থাপনার মধ্যে রূপান্তর করতে পারেন।

বিকল্প ও উন্নতি

  • সিঙ্গল-বাইট চরিত্রের এনকোডিংগুলি (যেমন আইএসও const wchar_t tt_iso88951[256] = {0,1,2,...};-8859-1) থেকে রূপান্তরগুলি সাধারণ অনুবাদ টেবিলের সাহায্যে এবং ইউসিএস 2 তে এবং রূপান্তর করার জন্য উপযুক্ত কোডের সাহায্যে উপলব্ধি করা যায়।

  • যদি ইউসিএস -2 যথেষ্ট না হয় তবে ইউসিএস -4 ( typedef std::basic_string<uint32_t> UCS2String) এ স্যুইচ করার চেয়ে

আইসিইউ বা অন্যান্য ইউনিকোড লাইব্রেরি?

উন্নত স্টাফ জন্য।


ডাং, দেশী ইউনিকোড সমর্থন নেই তা জানা ভাল নয়।
মিহাই ড্যানিলা

@ ফ্রনসী, আমি জানতে আগ্রহী যে আপনি গ্লিব :: অস্ট্রিংয়ের চেষ্টা করেছেন কিনা এবং যদি তাই হয় তবে আপনার চিন্তা কি?
ক্যারোলিন বেল্ট্রান

@ ক্যারোলাইনবেল্ট্রান: আমি গ্লিবকে জানি, তবে আমি কখনই এটি ব্যবহার করিনি, এবং আমি সম্ভবত এটি কখনও ব্যবহার করব না, কারণ এটি বরং একটি অপ্রয়োজনীয় লক্ষ্য প্ল্যাটফর্মের মধ্যে সীমাবদ্ধ (ইউনিক্সয়েড সিস্টেম ...)। এর উইন্ডোজ পোর্টটি বহিরাগত উইন 2 ইউনিক্স-স্তরের উপর ভিত্তি করে এবং সেখানে আইএমএইচও কোনও OSX- সামঞ্জস্যতা স্তর নেই। কমপক্ষে আমার কোডের জন্য (এই খিলান স্তরে ...) ;-) এই সমস্ত
স্টাফটি

9
ইউটিএফ -8 স্ট্রিংগুলিতে অনুসন্ধান করুন, প্রতিস্থাপন করুন এবং ঠিক ঠিক কাজ করে (কোনও চরিত্রের প্রতিনিধিত্বকারী বাইট ক্রমের একটি অংশকে অন্য চরিত্র হিসাবে কখনও ভুল ব্যাখ্যা করা যায় না)। প্রকৃতপক্ষে, ইউটিএফ -16 এবং ইউটিএফ -32 এটিকে মোটেও সহজ করে তোলে না: তিনটি এনকোডিং অনুশীলনে মাল্টিবাইট এনকোডিংস, কারণ কোনও ব্যবহারকারী-অনুভূতিযুক্ত অক্ষর (গ্রাফিম ক্লাস্টার) কোনও ইউনিকোড কোডপয়েন্ট দীর্ঘ হতে পারে! ব্যবহারিক সমাধানটি হ'ল সমস্ত কিছুর জন্য ইউটিএফ -8 ব্যবহার করা এবং উইন্ডোজ এপিআই-এর সাথে ডিল করার সময় কেবল ইউটিএফ -16 এ রূপান্তর করা।
ড্যানিয়েল

5
@ ফ্রানসী: ইউটিএফ -32 এর মতো ইউটিএফ -8 এর মতো ঠিক কাজগুলি অনুসন্ধান করুন এবং প্রতিস্থাপন করুন। এটি যথাযথভাবে কারণ সঠিক ইউনিকোড-সচেতন পাঠ্য প্রক্রিয়াকরণের জন্য ইউটিএফ -8 এর মতো পরিবর্তনশীল দৈর্ঘ্যের এনকোডিংটি স্ট্রিং প্রসেসিংটিকে আরও জটিল করে তোলে না multi সুতরাং সর্বত্র ইউটিএফ -8 ব্যবহার করুন। সাধারণ সি স্ট্রিং ফাংশনগুলি ইউটিএফ -8 (এবং ইউনিকোড স্ট্রিংয়ের মূল তুলনার সাথে মিল রেখে) কাজ করবে, এবং যদি আপনার আরও ভাষা-সচেতন প্রয়োজন হয় তবে আপনাকে ইউনিকোড লাইব্রেরিতে যেভাবেই কল করতে হবে, ইউটিএফ -16 / 32 আপনাকে এ থেকে বাঁচাতে পারে না।
ড্যানিয়েল

25
  1. আপনি যখন আপনার স্ট্রিংয়ে বিস্তৃত অক্ষর সংরক্ষণ করতে চান। wideবাস্তবায়ন উপর নির্ভর করে। আমি যদি সঠিকভাবে মনে রাখি তবে ভিজুয়াল সি ++ ডিফল্ট 16 বিট হয়, তবে জিসিসি লক্ষ্য অনুসারে ডিফল্ট হয়। এটি এখানে 32 বিট দীর্ঘ। দয়া করে নোট করুন wchar_t (প্রশস্ত চরিত্রের ধরণ) এর ইউনিকোডের সাথে কোনও সম্পর্ক নেই। এটি কেবল গ্যারান্টিযুক্ত যে এটি প্রয়োগ করতে সক্ষম হওয়া সবচেয়ে বড় চরিত্রের সমস্ত সদস্যকে যে প্রয়োগটি তার লোকেল দ্বারা সমর্থন করে এবং কমপক্ষে চর হিসাবে দীর্ঘস্থায়ী করতে পারে। আপনি এনকোডিংটি ব্যবহার করে খুব ভাল ইউনিকোড স্ট্রিং সংরক্ষণ করতে পারেন । তবে এটি ইউনিকোড কোড পয়েন্টগুলির অর্থ বুঝতে পারে না। সুতরাংstd::stringutf-8str.size()আপনার স্ট্রিংয়ে লজিক্যাল অক্ষরের পরিমাণ আপনাকে দেবে না, তবে কেবল সেই স্ট্রিং / wstring এ সঞ্চিত চর বা wchar_t উপাদানগুলির পরিমাণ। যে কারণে, জিটিকে / গ্লিব সি ++ র‌্যাপার লোকেরা একটি Glib::ustringক্লাস তৈরি করেছে যা utf-8 পরিচালনা করতে পারে।

    যদি আপনার wchar_t 32 বিট দীর্ঘ হয়, তবে আপনি utf-32একটি ইউনিকোড এনকোডিং হিসাবে ব্যবহার করতে পারেন এবং আপনি একটি নির্দিষ্ট (utf-32 নির্দিষ্ট দৈর্ঘ্য) এনকোডিং ব্যবহার করে ইউনিকোড স্ট্রিং সংরক্ষণ এবং পরিচালনা করতে পারেন । এর অর্থ আপনার wstring এর s.size()ফাংশন তারপরে wchar_t উপাদান এবং যৌক্তিক অক্ষরের সঠিক পরিমাণ ফেরত দেবে ।

  2. হ্যাঁ, চর সর্বদা কমপক্ষে 8 বিট দীর্ঘ হয়, যার অর্থ এটি সমস্ত ASCII মান সংরক্ষণ করতে পারে।
  3. হ্যাঁ, সমস্ত বড় সংকলক এটি সমর্থন করে।

আমি # 2 সম্পর্কে কৌতূহলী। আমি ভেবেছিলাম 7 টি বিট প্রযুক্তিগতভাবেও কার্যকর হবে? বা 7 বিট ASCII অক্ষরের অতীতের যে কোনও কিছু সঞ্চয় করতে সক্ষম হওয়া দরকার?
জলফ

1
হ্যাঁ, জলফ c89 তার সীমাবদ্ধতার ডকুমেন্টেশনে মৌলিক প্রকারের জন্য ন্যূনতম ব্যাপ্তিগুলি (স্বাক্ষরযুক্ত চরের জন্য, এটি 0..255 মিনিট) এবং পূর্ণসংখ্যার ধরণের জন্য খাঁটি বাইনারি সিস্টেম নির্দিষ্ট করে। এটি চরটি অনুসরণ করে, স্বাক্ষরবিহীন চর এবং স্বাক্ষরিত চরের সর্বনিম্ন বিট দৈর্ঘ্য 8. সি ++ এই নিয়মগুলির উত্তরাধিকার সূত্রে প্রাপ্ত।
জোহানেস স্কাউব -

15
"এর অর্থ আপনার wstring এর s.size () ফাংশনটি তারপরে wchar_t উপাদান এবং যৌক্তিক অক্ষরগুলির সঠিক পরিমাণ প্রদান করবে।" এটি পুরোপুরি সঠিক নয়, এমনকি ইউনিকোডের জন্যও। "লজিকাল চরিত্র" এর চেয়ে কোডডপয়েন্টটি বলা আরও সঠিক হবে, এমনকি ইউটিএফ -32-তে একটি প্রদত্ত চরিত্রটি একাধিক কোডপয়েন্ট দ্বারা গঠিত হতে পারে।
লোগান ক্যাপাল্ডো

আপনি কি সংক্ষেপে বলছেন যে ইউনিকোড চরিত্রের সেটটির জন্য সি ++ এর স্থানীয় সমর্থন নেই?
মিহাই ড্যানিলা

1
"তবে এটি ইউনিকোড কোড পয়েন্টের অর্থ বুঝতে পারে না।" উইন্ডোতে, না std::wstring
ডেলিপ্লিকেটর

5

আমি প্রায়শই কোনও সমস্যা ছাড়াই utf-8 অক্ষর ধরে রাখতে std :: স্ট্রিং ব্যবহার করি। এপিআই এর সাথে ইন্টারফেস করার সময় আমি আন্তরিকভাবে এটি করার পরামর্শ দিচ্ছি যা দেশীয় স্ট্রিং টাইপ হিসাবে utf-8 ব্যবহার করে।

উদাহরণস্বরূপ, টিসিএল ইন্টারপ্রেটারের সাথে আমার কোড ইন্টারফেস করার সময় আমি utf-8 ব্যবহার করি।

প্রধান ক্যাভিটটি স্ট্যান্ড :: স্ট্রিংয়ের দৈর্ঘ্য, স্ট্রিংয়ের অক্ষরের সংখ্যা আর নেই।


1
জুয়ান: আপনার অর্থ কি স্ট্যান্ড :: স্ট্রিংটি সমস্ত ইউনিকোড অক্ষর ধরে রাখতে পারে তবে দৈর্ঘ্যটি ভুলভাবে প্রতিবেদন করবে? এটির কোনও দৈর্ঘ্য ভুল রিপোর্ট করার কোনও কারণ আছে?

3
Utf-8 এনকোডিং ব্যবহার করার সময়, একক ইউনিকোড অক্ষর একাধিক বাইট সমন্বয়ে গঠিত হতে পারে। এই কারণেই স্ট্যান্ডার্ড অ্যাস্কি সেট থেকে বেশিরভাগ অক্ষর ব্যবহার করার সময় utf-8 এনকোডিং ছোট হয় is ইউনিকোড অক্ষরের সংখ্যা পরিমাপ করতে আপনাকে বিশেষ ফাংশন (বা নিজের রোল) ব্যবহার করতে হবে।

2
(উইন্ডোজ নির্দিষ্ট) বেশিরভাগ ফাংশন আশা করবে যে বাইটগুলি ব্যবহার করে স্ট্রিংটি ASCII এবং 2 বাইট ইউনিকোড, পুরানো সংস্করণ এমবিসিএস। যার অর্থ আপনি যদি 8 বিট ইউনিকোড সঞ্চয় করে থাকেন তবে একটি স্ট্যান্ডার্ড উইন্ডোজ ফাংশনটি কল করতে আপনাকে 16 বিট ইউনিকোডে রূপান্তর করতে হবে (যদি আপনি কেবল ASCII অংশ ব্যবহার না করেন)।
গ্রেগ ডোমজান

2
একটি std :: স্ট্রিং দৈর্ঘ্যকে ভুলভাবে প্রতিবেদন করবে না, তবে এটি ভুল স্ট্রিংটিকেও আউটপুট করবে। যদি ইউটিএফ -8 এ কিছু ইউনিকোড চরিত্রকে একাধিক বাইট হিসাবে উপস্থাপন করা হয়, যা স্টাড :: স্ট্রিং তার নিজস্ব অক্ষর হিসাবে বিবেচনা করে, তবে আপনার সাধারণত স্ট্যান্ড :: স্ট্রিং ম্যানিপুলেশন রুটিনগুলি সম্ভবত একাধিক অদ্ভুত অক্ষরকে আউটপুট দেবে যা একটির ভুল ব্যাখ্যা দ্বারা ফলাফল করে সঠিক চরিত্র।
মিহাই ড্যানিলা

2
আমি উত্তরটি পরিবর্তনের পরামর্শ দিচ্ছি যে স্ট্রিংগুলি কেবলমাত্র বাইটের ধারক হিসাবে বিবেচনা করা উচিত এবং যদি বাইটগুলি কিছু ইউনিকোড এনকোডিং হয় (ইউটিএফ -8, ইউটিএফ -16, ...), তবে আপনার নির্দিষ্ট লাইব্রেরি ব্যবহার করা উচিত যা বোঝে যে। স্ট্যান্ডার্ড স্ট্রিং-ভিত্তিক এপিআই (দৈর্ঘ্য, সাবস্ট্রাস্ট, ইত্যাদি) সমস্ত মাল্টিবাইট অক্ষরের সাথে খারাপভাবে ব্যর্থ হবে। যদি এই আপডেটটি করা হয় তবে আমি আমার ডাউনভোটটি সরিয়ে দেব।
মিহাই ড্যানিলা 14 ই

4
  1. আপনি যখন 'প্রশস্ত' (ইউনিকোড) অক্ষর সংরক্ষণ করতে চান।
  2. হ্যাঁ: তাদের মধ্যে 255 (0 বাদে)।
  3. হ্যাঁ.
  4. এখানে একটি প্রারম্ভিক নিবন্ধ: http://www.joelonsoftware.com/articles/Unicode.html

11
স্ট্যান্ড :: স্ট্রিং 0 টি ঠিক রাখতে পারে (আপনি যদি c_str () পদ্ধতিটি কল করেন তবে কেবল সাবধান হন)
মিঃ ফুজ

3
এবং কঠোরভাবে বলতে গেলে, একটি চর 8 বিট হওয়ার গ্যারান্টিযুক্ত নয়। :) # 4 এ আপনার লিঙ্কটি অবশ্যই পড়তে হবে তবে আমি মনে করি না এটি প্রশ্নের উত্তর দেয়। একটি প্রশস্ত চরিত্রটি ইউনিকোডের সাথে কঠোরভাবে কিছু করার নয়। এটি কেবল একটি বিস্তৃত চরিত্র। (ওএসের উপর কত বিস্তৃত নির্ভর করে তবে সাধারণত 16 বা 32 বিট)
জাল্ফ

2
  1. যখন আপনি ইউনিকোড স্ট্রিংগুলি ব্যবহার করতে চান এবং কেবল এসকিই নয়, আন্তর্জাতিকীকরণের জন্য সহায়ক
  2. হ্যাঁ, তবে এটি 0 দিয়ে ভাল খেলছে না
  3. যে কিছুই না সম্পর্কে সচেতন না
  4. প্রশস্ত চরিত্র হ'ল একটি ইউনিকোড চরিত্রের নির্দিষ্ট দৈর্ঘ্যের উপস্থাপনা পরিচালনা করার সংকলক নির্দিষ্ট উপায়, এমএসভিসির জন্য এটি একটি 2 বাইট অক্ষর, জিসিসি-র জন্য আমি বুঝতে পারি এটি 4 বাইট। এবং http://www.joelonsoftware.com/articles/Unicode.html এর জন্য একটি +1

1
২. স্ট্যান্ড :: স্ট্রিং একটি নুল অক্ষর ঠিক ঠিক রাখতে পারে। এটি পাশাপাশি utf-8 এবং প্রশস্ত অক্ষরও ধারণ করতে পারে।

@ জুয়ান: এটি আমাকে আবার বিভ্রান্তিতে ফেলেছে। যদি স্টাড :: স্ট্রিংটি ইউনিকোড অক্ষর রাখতে পারে তবে স্টাড :: ডাবল স্ট্রিংয়ের সাথে বিশেষ কী?

1
@ অ্যাপু: স্ট্যান্ড :: স্ট্রিংটি ইউটিএফ -8 ইউনিকোড অক্ষর ধারণ করতে পারে। বিভিন্ন অক্ষরের প্রস্থকে লক্ষ্য করে অনেকগুলি ইউনিকোড মান রয়েছে। UTf8 8 বিট প্রশস্ত। ইউটিএফ -16 এবং ইউটিএফ -32 যথাক্রমে 16 এবং 32 বিট প্রশস্ত রয়েছে
গ্রেগ ডি

একটি স্ট্যান্ড :: wstring সহ। নির্দিষ্ট দৈর্ঘ্যের এনকোডিংগুলি ব্যবহার করার সময় প্রতিটি ইউনিকোড অক্ষর এক wchar_t হতে পারে। উদাহরণস্বরূপ, আপনি যদি গ্রেগের লিঙ্ক হিসাবে সফ্টওয়্যার পদ্ধতির জোলটি বেছে নেন। তারপরে wstring এর দৈর্ঘ্য হ'ল স্ট্রিংয়ের ইউনিকোড অক্ষরের সংখ্যা। তবে এটি আরও স্থান নেয়

আমি বলিনি যে এটি 0 '\ 0' ধরে রাখতে পারে না, এবং আমি যেটা ভাল খেলতে চাইছি তা হ'ল কিছু পদ্ধতি আপনাকে wstring এর সমস্ত ডেটা সমেত একটি প্রত্যাশিত ফলাফল দিতে পারে না। নিচে ভোটের উপর তাই কঠোর।
গ্রেগ ডোমজান

2

যে অ্যাপ্লিকেশনগুলি কেবল 256 টি ভিন্ন অক্ষরের সাথে সন্তুষ্ট নয় তাদের কাছে হয় বিস্তৃত অক্ষর (8 বিটের বেশি) বা ভেরিয়েবল-দৈর্ঘ্যের এনকোডিং (সি ++ টার্মিনোলজিতে একটি মাল্টিবাইট এনকোডিং) যেমন ইউটিএফ -8 ব্যবহারের বিকল্প রয়েছে। প্রশস্ত অক্ষরগুলিতে সাধারণত একটি চলক দৈর্ঘ্যের এনকোডিংয়ের চেয়ে বেশি স্থানের প্রয়োজন হয় তবে প্রক্রিয়াটি দ্রুত হয়। বহু-ভাষা অ্যাপ্লিকেশনগুলি যে বিপুল পরিমাণে পাঠ্য প্রক্রিয়াকরণ করে পাঠ্য প্রসেস করার সময় সাধারণত বিস্তৃত অক্ষর ব্যবহার করে, তবে এটি ডিস্কে সংরক্ষণের সময় এটি ইউটিএফ -8 এ রূপান্তর করে।

A stringএবং a এর মধ্যে একমাত্র পার্থক্য wstringহ'ল তারা যে অক্ষরগুলি সঞ্চয় করে তার ডেটা টাইপ। একটি স্ট্রিং স্টোর charযার আকার কমপক্ষে 8 টি বিট হওয়ার গ্যারান্টিযুক্ত তাই আপনি প্রক্রিয়াকরণের জন্য স্ট্রিং যেমন ASCII, ISO-8859-15, বা UTF-8 পাঠ্য ব্যবহার করতে পারেন। মান অক্ষর সেট বা এনকোডিং সম্পর্কে কিছুই বলে না।

কার্যত প্রতিটি সংকলক একটি অক্ষর সেট ব্যবহার করে যার প্রথম 128 টি অক্ষর ASCII এর সাথে মিলে যায়। এটি ইউটিএফ -8 এনকোডিং ব্যবহারকারী সংকলকগুলির ক্ষেত্রেও এটি। ইউটিএফ -8 বা অন্য কিছু পরিবর্তনশীল-দৈর্ঘ্যের এনকোডিংয়ের ক্ষেত্রে স্ট্রিংগুলি ব্যবহার করার সময় সচেতন হওয়া গুরুত্বপূর্ণ বিষয়টি হ'ল সূচকগুলি এবং দৈর্ঘ্যগুলি অক্ষরে নয়, বাইটে পরিমাপ করা হয়।

একটি স্ট্রিংয়ের ডেটা টাইপ wchar_t, যার আকার স্ট্যান্ডার্ডে সংজ্ঞায়িত করা হয় না, এটি ছাড়াও এটি কমপক্ষে একটি চর হিসাবে কমপক্ষে বড় হতে হবে, সাধারণত 16 বিট বা 32 বিট। wstring বাস্তবায়ন সংজ্ঞায়িত প্রশস্ত অক্ষর এনকোডিং পাঠ্য প্রক্রিয়াকরণের জন্য ব্যবহার করা যেতে পারে। এনকোডিংটি স্ট্যান্ডার্ডে সংজ্ঞায়িত না হওয়ায় স্ট্রিং এবং উইস্ট্রিংয়ের মধ্যে রূপান্তর করা সোজা নয়। যে কোনও একটি স্থির দৈর্ঘ্যের এনকোডিংয়ের জন্য রাইটিংগুলিকে ধরে নিতে পারে না।

আপনার যদি বহু-ভাষা সমর্থন প্রয়োজন না হয় তবে আপনি কেবল নিয়মিত স্ট্রিং ব্যবহার করেই ঠিক থাকতে পারেন। অন্যদিকে, আপনি যদি একটি গ্রাফিকাল অ্যাপ্লিকেশন লিখছেন তবে প্রায়শই এমন হয় যে এপিআই কেবল বিস্তৃত অক্ষরকেই সমর্থন করে। তারপরে আপনি সম্ভবত পাঠ্যের প্রক্রিয়া করার সময় একই বিস্তৃত অক্ষরগুলি ব্যবহার করতে চান। মনে রাখবেন যে ইউটিএফ -16 হ'ল একটি পরিবর্তনশীল দৈর্ঘ্যের এনকোডিং, যার অর্থ আপনি length()অক্ষরের সংখ্যা ফিরিয়ে নিতে অনুমান করতে পারবেন না । যদি ইউপিএস-এ কোনও স্থির-দৈর্ঘ্যের এনকোডিং যেমন ইউসিএস -২ ব্যবহার করে তবে প্রক্রিয়াজাতকরণ সহজ হয়ে যায়। প্রশস্ত অক্ষর এবং ইউটিএফ -8 এর মধ্যে রূপান্তর করা পোর্টেবল উপায়ে করা কঠিন, তবে তারপরে আবার আপনার ইউজার ইন্টারফেস এপিআই সম্ভবত রূপান্তরকে সমর্থন করে।


সুতরাং, প্রথম অনুচ্ছেদে প্যারাফ্রেসিং: অ্যাপ্লিকেশনটির জন্য 256 টিরও বেশি অক্ষরের প্রয়োজন একটি মাল্টবাইট-এনকোডিং বা সম্ভবত_মলটিবায়িট-এনকোডিং ব্যবহার করা উচিত।
হস্তান্তরকারী

সাধারণত 16 এবং 32 বিট এনকোডিংগুলি যেমন ইউসিএস -2 এবং ইউসিএস -4 এ মাল্টিবাইট এনকোডিং বলা হয় না। সি ++ স্ট্যান্ডার্ডটি মাল্টিবাইট এনকোডিংগুলি এবং প্রশস্ত অক্ষরের মধ্যে পার্থক্য করে। একটি বিস্তৃত অক্ষরের প্রতিনিধিত্ব প্রতি অক্ষরটিতে একটি নির্দিষ্ট সংখ্যা (সাধারণত 8 এর বেশি) বিট ব্যবহার করে। সর্বাধিক প্রচলিত অক্ষরগুলি এনকোড করতে একক বাইট ব্যবহার করা এবং বাকী অক্ষর সেটটি এনকোড করার জন্য একাধিক বাইট ব্যবহার করা এনকোডিংগুলিকে মাল্টিবাইট এনকোডিংগুলি বলা হয়।
সেপ্পো এনার্ভি

দুঃখিত, ঘোলা মন্তব্য। পরিবর্তনশীল দৈর্ঘ্যের এনকোডিং বলা উচিত ছিল। ইউটিএফ -16 হ'ল ইউটিএফ -8 এর মতো একটি পরিবর্তনশীল-দৈর্ঘ্য-এনকোডিং। এটি ভান করা খারাপ ধারণা নয় is
উত্সাহক

এটা একটা ভাল দিক. ইউটিএফ -16 (ইউসিএস -2 এর পরিবর্তে) সংরক্ষণের জন্য কেন উইস্ট্রিংগুলি ব্যবহার করা যায় না তার কোনও কারণ নেই, তবে তারপরে একটি নির্দিষ্ট দৈর্ঘ্যের এনকোডিংয়ের সুবিধাটি হারিয়ে যায়।
সেপ্পো এনারভি

2

একটি ভাল প্রশ্ন! আমি মনে করি যে কোনও ফাইলের মাধ্যমে ডেটা সংরক্ষণ করতে বা কোনও নেটওয়ার্কের মাধ্যমে ডেটা স্থানান্তর করার জন্য ডেটা এনকোডিং (কখনও কখনও একটি চিঠিও জড়িত থাকে) একটি স্মৃতি এক্সপ্রেশন মেকানিজম, তাই আমি এই প্রশ্নের উত্তর হিসাবে দেব:

১. কখন আমার স্টাড :: স্ট্রিং ওভার স্ট্রিং :: স্ট্রিং ব্যবহার করা উচিত?

যদি প্রোগ্রামিং প্ল্যাটফর্ম বা এপিআই ফাংশনটি একটি একক বাইট হয় এবং আমরা কিছু ইউনিকোড ডেটা প্রক্রিয়া করতে বা পার্স করতে চাই, যেমন উইন্ডোজ'আরইজি ফাইল বা নেটওয়ার্ক 2-বাইট স্ট্রিম থেকে পড়া, আমাদের সহজেই স্ট্যান্ড :: ডাব্লু স্ট্রিং ভেরিয়েবল ঘোষণা করা উচিত তাদের প্রক্রিয়া। উদাহরণস্বরূপ: wstring ws = L "中国 a" (6 octets মেমরি: 0x4E2D 0x56FD 0x0061), আমরা অক্ষর '中' পেতে ws [0] এবং's 'এবং ডাব্লুএস [2] পেতে ব্যবহার করতে পারি অক্ষর 'ক' ইত্যাদি পান

২. এসডিডি :: স্ট্রিংগুলি বিশেষ অক্ষরগুলি সহ পুরো ASCII অক্ষর সেটটি ধরে রাখতে পারে?

হ্যাঁ. তবে বিজ্ঞপ্তি: আমেরিকান এএসসিআইআই, মানে প্রতিটি 0x00 ~ 0xFF অক্টেট একটি অক্ষরকে বোঝায়, "123abc & * _ &" এর মতো মুদ্রণযোগ্য পাঠ্য সহ এবং আপনি বিশেষ বলেছিলেন, বেশিরভাগই এটি 'হিসাবে মুদ্রণ করে।' বিভ্রান্তিকর সম্পাদক বা টার্মিনালগুলি এড়িয়ে চলুন। এবং অন্যান্য কিছু দেশ তাদের নিজস্ব "এএসসিআইআই" চরসেট প্রসারিত করে, যেমন চীনা, একটি অক্ষরের পক্ষে দাঁড়ানোর জন্য 2 টি অক্টেট ব্যবহার করে।

3.Idd :: wstring সব জনপ্রিয় সি ++ সংকলক দ্বারা সমর্থিত?

হতে পারে, বা বেশিরভাগ ক্ষেত্রেই। আমি ব্যবহার করেছি: ভিসি ++ 6 এবং জিসিসি 3.3, হ্যাঁ

৪. "বিস্তৃত চরিত্র" আসলে কী?

একটি বিস্তৃত অক্ষর সাধারণত সমস্ত দেশের অক্ষর ধরে রাখতে 2 টি অক্টেট বা 4 অক্টেট ব্যবহার করে তা নির্দেশ করে। 2 অক্টেট ইউসিএস 2 একটি প্রতিনিধি নমুনা, এবং আরও উদাহরণস্বরূপ ইংরাজী 'এ', এর মেমরি 0x0061 এর 2 অক্টেট (এএসসিআইআই মধ্যে বনাম) এর স্মৃতি 1 অক্টেট 0x61)


0

এখানে খুব ভাল উত্তর রয়েছে তবে আমি মনে করি উইন্ডোজ / ভিজ্যুয়াল স্টুডিও সম্পর্কিত কয়েকটি জিনিস যুক্ত করতে পারি। টিএসটি ভিএস ২০১৫ এর সাথে আমার অভিজ্ঞতার ভিত্তিতে তৈরি। লিনাক্সে, মূলত উত্তরটি হ'ল ইউটিএফ -8 std::stringসর্বত্র এনকোডযুক্ত ব্যবহার করা । উইন্ডোজ / ভিএস এ এটি আরও জটিল হয়। এখানে কেন। উইন্ডোজ charলোকেল কোডপেজ ব্যবহার করে এন ব্যবহার করে স্ট্রিংগুলি এনকোড করার আশা করে । এটি প্রায় সবসময় আপনার অবস্থানের উপর নির্ভর করে অন্যান্য বিশেষ অক্ষর অনুসারে ASCII অক্ষর সেট থাকে। আমাকে কেবল উল্লেখ করতেই পারি যে এটি উইন্ডোজ এপিআই ব্যবহার করার সময় নয়, আরও তিনটি বড় জায়গা রয়েছে যেখানে স্ট্রিংগুলি স্ট্যান্ডার্ড সি ++ এর সাথে ইন্টারঅ্যাক্ট করে। এগুলি স্ট্রিং লিটারাল, কোনও ফাইলের নাম std::coutব্যবহার <<এবং পাস করার আউটপুট std::fstream

আমি এখানে উপস্থিত হব যে আমি একজন প্রোগ্রামার, কোনও ভাষা বিশেষজ্ঞ নন। আমি প্রশংসা করি যে ইউএসসি 2 এবং ইউটিএফ -16 এক নয়, তবে আমার উদ্দেশ্যগুলির জন্য এগুলি বিনিময়যোগ্য হওয়ার পক্ষে যথেষ্ট এবং আমি তাদের এখানে ব্যবহার করি use উইন্ডোজ কোনটি ব্যবহার করে আমি আসলে তা নিশ্চিত নই, তবে সাধারণত আমারও জানা দরকার হয় না। আমি এই উত্তরে ইউসিএস 2 বলেছি, তাই দুঃখিত, যদি আমি এই বিষয়ে আমার অজ্ঞতা নিয়ে কাউকে বিরক্ত করি এবং আমার কিছু ভুল হয় তবে আমি এটি পরিবর্তন করতে পেরে খুশি।

স্ট্রিং আক্ষরিক

যদি আপনি স্ট্রিং লিটারেলগুলি প্রবেশ করেন যা কেবলমাত্র অক্ষরগুলি ধারণ করে যা আপনার কোডপেজ দ্বারা উপস্থাপিত হতে পারে তবে ভিএস আপনার কোডেজের উপর ভিত্তি করে অক্ষর এনকোডিংয়ের জন্য প্রতি বাইট 1 বাইট দিয়ে আপনার ফাইলে এগুলি সংরক্ষণ করে। মনে রাখবেন যে আপনি যদি নিজের কোডপেজ পরিবর্তন করেন বা অন্য উত্স বিকাশকারীকে একটি ভিন্ন কোড পৃষ্ঠা ব্যবহার করে আপনার উত্সটি দেন তবে আমি মনে করি (তবে পরীক্ষা করে দেখিনি) অক্ষরটি আলাদা হয়ে যাবে। আপনি যদি কোনও আলাদা কোড পৃষ্ঠা ব্যবহার করে কম্পিউটারে আপনার কোড চালনা করেন তবে আমি নিশ্চিত নই যে চরিত্রটিও খুব বদলে যাবে কিনা।

যদি আপনি এমন কোনও স্ট্রিং লিটারেল লিখেন যা আপনার কোডপেজ দ্বারা প্রতিনিধিত্ব করা যায় না তবে ভিএস আপনাকে ফাইলটি ইউনিকোড হিসাবে সংরক্ষণ করতে বলবে। ফাইলটি তখন ইউটিএফ -8 হিসাবে এনকোড হবে। এর অর্থ হ'ল সমস্ত নন ASCII অক্ষর (আপনার কোডডে থাকা এমনগুলি সহ) 2 বা ততোধিক বাইট দ্বারা উপস্থাপিত হবে। এর অর্থ আপনি যদি আপনার উত্স অন্য কাউকে দেন তবে উত্সটি দেখতে একই রকম হবে। যাইহোক, সংকলকটিতে উত্সটি প্রেরণ করার আগে, ভিএস ইউটিএফ -8 এনকোডযুক্ত পাঠ্যকে কোড পৃষ্ঠা এনকোডযুক্ত পাঠ্যে রূপান্তর করে এবং কোড পৃষ্ঠা থেকে নিখোঁজ যে কোনও অক্ষরের সাথে প্রতিস্থাপন করা হয় ?

ভিএস-তে কোনও ইউনিকোড স্ট্রিং আক্ষরিকভাবে সঠিকভাবে উপস্থাপনের গ্যারান্টি দেওয়ার একমাত্র উপায় হ'ল স্ট্রিং আক্ষরিককে Lএকটি প্রশস্ত স্ট্রিং আক্ষরিক তৈরি করার আগে ce এই ক্ষেত্রে ভিএস ফাইলটি থেকে ইউটিএফ -8 এনকোডযুক্ত পাঠ্যটিকে ইউসিএস 2 তে রূপান্তর করবে। তারপরে আপনাকে এই স্ট্রিংটি আক্ষরিকভাবে একটি std::wstringকনস্ট্রাক্টরে পাস করতে হবে বা আপনাকে এটি utf-8 এ রূপান্তর করতে হবে এবং এটিতে স্থাপন করতে হবে std::string। অথবা আপনি যদি চান আপনার উইন্ডোজ এপিআই ফাংশনগুলি কোড কোডটি ব্যবহার করে এটিকে এনকোড করতে ব্যবহার করতে পারেন তবে এটির std::stringপরেও আপনি প্রশস্ত স্ট্রিং আক্ষরিক ব্যবহার করতে পারেন নি।

এসটিডি :: cout

কনসোলটি ব্যবহার করে আউটপুট দেওয়ার সময় <<আপনি কেবল ব্যবহার করতে পারেন std::string, না std::wstringএবং আপনার স্থানীয় কোড কোড ব্যবহার করে পাঠ্যটি এনকোড করতে হবে। আপনার যদি একটি থাকে std::wstringতবে আপনাকে অবশ্যই এটির উইন্ডোজ এপিআই ফাংশনগুলির একটির ব্যবহার করে রূপান্তর করতে হবে এবং আপনার কোডপেজে থাকা কোনও অক্ষর দ্বারা প্রতিস্থাপন করা হবে ?(সম্ভবত আপনি চরিত্রটি পরিবর্তন করতে পারেন, আমি মনে করতে পারি না)।

std :: fstream ফাইলের নাম

উইন্ডোজ ওএস এর ফাইলনামগুলির জন্য ইউসিএস 2 / ইউটিএফ -16 ব্যবহার করে তাই আপনার কোডপেজ যা-ই হোক না কেন আপনার কোনও ইউনিকোড অক্ষরযুক্ত ফাইল থাকতে পারে। তবে এর অর্থ হ'ল আপনার কোডপেজটিতে না থাকা অক্ষরগুলি সহ ফাইলগুলি অ্যাক্সেস করতে বা তৈরি করতে আপনাকে অবশ্যই ব্যবহার করতে হবে std::wstring। অন্য কোন উপায় নেই। এটি একটি মাইক্রোসফ্ট নির্দিষ্ট এক্সটেনশন যা std::fstreamসম্ভবত অন্যান্য সিস্টেমে সংকলন করবে না। আপনি যদি std :: স্ট্রিং ব্যবহার করেন তবে আপনি কেবল ফাইল কোড ব্যবহার করতে পারেন যা কেবল আপনার কোডেজে অক্ষর অন্তর্ভুক্ত করে।

আপনার বিকল্পগুলি

আপনি যদি কেবল লিনাক্সে কাজ করছেন তবে আপনি সম্ভবত এটি এতদিন পেতেন না। std::stringসর্বত্র ইউটিএফ -8 ব্যবহার করুন ।

আপনি যদি উইন্ডোজটিতে স্রেফ কাজ করে থাকেন তবে std::wstringসর্বত্র ইউসিএস 2 ব্যবহার করুন । কিছু পিউরিস্টরা বলতে পারে ইউটিএফ 8 ব্যবহার করুন তারপরে প্রয়োজনে রূপান্তর করুন তবে কেন ঝামেলা সহ্য করবেন না।

আপনি যদি ক্রস প্ল্যাটফর্ম হন তবে স্পষ্ট করে বলার জন্য এটি গোলযোগ। আপনি যদি উইন্ডোজের যেকোন জায়গায় ইউটিএফ -8 ব্যবহার করার চেষ্টা করেন তবে আপনার স্ট্রিং আক্ষরিক এবং কনসোলে আউটপুট নিয়ে আপনাকে সত্যিই যত্নবান হওয়া দরকার। আপনি সেখানে সহজেই আপনার স্ট্রিংগুলিকে দূষিত করতে পারেন। আপনি যদি std::wstringলিনাক্সের সর্বত্র ব্যবহার করেন তবে আপনার বিস্তৃত সংস্করণে অ্যাক্সেস নাও থাকতে পারে std::fstream, তাই আপনাকে রূপান্তরটি করতে হবে, তবে দুর্নীতির কোনও ঝুঁকি নেই। সুতরাং ব্যক্তিগতভাবে আমি এটি একটি ভাল বিকল্প মনে করি। অনেকের সাথে একমত হবে না, তবে আমি একা নই - উদাহরণস্বরূপ এটি ডাব্লুউইজেডস দ্বারা নেওয়া পথ।

অন্য বিকল্পটি লিনাক্স এবং উইন্ডোজে টাইপফেরফের unicodestringমতো হতে পারে std::stringএবং std::wstringইউএনআই () নামে একটি ম্যাক্রো থাকতে পারে যা উইন্ডোজে এল উপস্থাপন করে এবং লিনাক্সে কিছুই নেই, তারপরে কোডটি

#include <fstream>
#include <string>
#include <iostream>
#include <Windows.h>

#ifdef _WIN32
typedef std::wstring unicodestring;
#define UNI(text) L ## text
std::string formatForConsole(const unicodestring &str)
{
    std::string result;
    //Call WideCharToMultiByte to do the conversion
    return result;
}
#else
typedef std::string unicodestring;
#define UNI(text) text
std::string formatForConsole(const unicodestring &str)
{
    return str;
}
#endif

int main()
{

    unicodestring fileName(UNI("fileName"));
    std::ofstream fout;
    fout.open(fileName);
    std::cout << formatForConsole(fileName) << std::endl;
    return 0;
}

আমি মনে করি যে কোনও প্ল্যাটফর্মের জন্য ঠিক থাকবে।

উত্তর

সুতরাং আপনার প্রশ্নের উত্তর

1) আপনি যদি উইন্ডোজের জন্য প্রোগ্রামিং করেন তবে সর্বদা যদি ক্রস প্ল্যাটফর্ম হয় তবে সম্ভবত সর্বদা, যদি আপনি উইন্ডোজে সম্ভাব্য দুর্নীতির সমস্যাগুলি মোকাবেলা করতে না চান বা #ifdefsপার্থক্যের বিষয়ে কাজ করার জন্য নির্দিষ্ট প্ল্যাটফর্ম সহ কিছু কোড না লিখে থাকেন , যদি কেবল ব্যবহার করে লিনাক্স তারপর কখনও না।

2) হ্যাঁ। লিনাক্সের পাশাপাশি আপনি এটি সমস্ত ইউনিকোডের জন্যও ব্যবহার করতে পারেন। উইন্ডোজে আপনি কেবল ইউটিএফ -8 ব্যবহার করে ম্যানুয়ালি এনকোড করা বেছে নিলে আপনি সমস্ত ইউনিকোডের জন্যই এটি ব্যবহার করতে পারবেন। তবে উইন্ডোজ এপিআই এবং স্ট্যান্ডার্ড সি ++ ক্লাসগুলি std::stringলোকেল কোডেপেজ ব্যবহার করে এনকোড হওয়া আশা করবে । এতে সমস্ত এএসসিআইআই প্লাস এবং আরও একটি 128 টি অক্ষর অন্তর্ভুক্ত রয়েছে যা আপনার কম্পিউটারের কোডপেজ ব্যবহারের জন্য সেটআপ করা আছে তার উপর নির্ভর করে পরিবর্তিত হয়।

3) আমি এটি বিশ্বাস করি, তবে তা না হলে এটি কেবল 'স্টাড :: বেসিক_স্ট্রিং'-এর wchar_tপরিবর্তে ব্যবহার করে সাধারণ টাইপডেফchar

4) প্রশস্ত অক্ষর একটি অক্ষর টাইপ যা 1 বাইট স্ট্যান্ডার্ড charটাইপের চেয়ে বড় । উইন্ডোজে এটি 2 বাইট, লিনাক্সে এটি 4 বাইট।


1
সম্পর্কিত "তবে, সংকলকে উত্সটি প্রেরণ করার আগে, ভিএস ইউটিএফ -8 এনকোডযুক্ত পাঠ্যকে কোড পৃষ্ঠা এনকোডযুক্ত পাঠ্যে রূপান্তর করে এবং কোড পৃষ্ঠা থেকে নিখোঁজ হওয়া কোনও অক্ষর? দিয়ে প্রতিস্থাপিত হয়?" -> সংকলকটি ইউটিএফ -8 এনকোডিং (ব্যবহার /utf-8) ব্যবহার করলে আমি এটি সত্য বলে মনে করি না ।
রুই ড্যান্টন

আমি এটি বিকল্প হিসাবে সচেতন ছিলাম না। এই লিঙ্কটি থেকে ডকস.মাইক্রোসফট.ইন- ইউএস / সিপি / বিল্ড / রেফারেন্স/… মনে হচ্ছে প্রকল্পের বৈশিষ্ট্যগুলিতে নির্বাচন করার জন্য কোনও টিক বাক্স নেই, আপনাকে অবশ্যই এটি একটি অতিরিক্ত কমান্ড লাইন বিকল্প হিসাবে যুক্ত করতে হবে। ভাল জায়গা!
ফিল রোজেনবার্গ

-2

1) গ্রেগ দ্বারা উল্লিখিত হিসাবে, wstring আন্তর্জাতিকীকরণের জন্য সহায়ক, আপনি যখন ইংরেজী ব্যতীত অন্য ভাষায় আপনার পণ্য প্রকাশ করবেন that's

৪) প্রশস্ত চরিত্রের জন্য এটি পরীক্ষা করে দেখুন http://en.wikedia.org/wiki/ wides_character


-6

কখন আপনি প্রশস্ত অক্ষর ব্যবহার করবেন না?

আপনি যখন 1990 সালের আগে কোড লিখছেন।

স্পষ্টতই, আমি ফ্লিপ করছি, তবে সত্যই, এটি এখন একবিংশ শতাব্দীর। 127 টি অক্ষর যথেষ্ট পর্যায়ে থেকে শেষ হয়েছে। হ্যাঁ, আপনি ইউটিএফ 8 ব্যবহার করতে পারেন, তবে মাথাব্যথা নিয়ে কেন বিরক্ত হন?


16
@ ডেভ: আমি জানি না ইউটিএফ -8 কী মাথাব্যথা তৈরি করে যা উইডাচার্সের (ইউটিএফ -16) এর চেয়ে বড়। ইউটিএফ -16 এ আপনার একাধিক অক্ষর রয়েছে।
পাভেল রদজিভিলভস্কি

সমস্যাটি হ'ল আপনি যদি আর কোথাও না থাকেন তবে ইংলিশ স্পিকারের দেশ আপনি wchar_t ব্যবহার করতে OUGHT। কিছু বর্ণমালার বাইটে ফিট করার চেয়ে আরও বেশি অক্ষর রয়েছে তা উল্লেখ করার দরকার নেই। আমরা সেখানে ছিলাম, ডস এ। কোডপেজ সিজোফ্রেনিয়া, না, ধন্যবাদ, আর কিছু নয় ..
সুইফট - শুক্রবার পাই

1
@ সুইফট সমস্যাটি wchar_tহ'ল এর আকার এবং অর্থটি ওএস-নির্দিষ্ট। এটি কেবল নতুন সমস্যাগুলির সাথে পুরানো সমস্যাগুলিকে অদলবদল করে। যদিও একটি ওএস (নির্ধারিত প্ল্যাটফর্মগুলিতে, অন্তত) নির্বিশেষে charis charসুতরাং আমরা পাশাপাশি কেবল ইউটিএফ -8 ব্যবহার করতে পারি, সমস্ত কিছুকে এসের ক্রমগুলিতে প্যাক করি charএবং বিলাপ করি যে কীভাবে সি ++ পরিমাপ, সূচীকরণ, ইত্যাদির জন্য কোনও মানক পদ্ধতি ছাড়াই আমাদের নিজের উপর সম্পূর্ণভাবে ফেলে দেয়।
আন্ডারস্কোর_১১

1
@ সুইফট আপনি সম্পূর্ণ পেছনের দিকে বলে মনে হচ্ছে। wchar_tএকটি নির্দিষ্ট-প্রস্থের ডেটা টাইপ, সুতরাং 10 এর অ্যারে wchar_tসর্বদা sizeof(wchar_t) * 10প্ল্যাটফর্ম বাইট দখল করবে । এবং ইউটিএফ -16 হ'ল একটি পরিবর্তনশীল-প্রস্থের এনকোডিং যাতে অক্ষরগুলি 1 বা 2 16-বিট কোডপয়েন্ট (এবং UTF-8 এর জন্য s / 16/8 / g) দ্বারা গঠিত হতে পারে।
আন্ডারস্কোর_১১

1
উইন্ডোতে স্ট্রিংয়ের @ স্টিভোল্ল্যাশ wchar_t উপস্থাপনাটি এফএফএফএফের চেয়ে বড় অক্ষরকে বিশেষ সার্গেট জুটি হিসাবে এনকোড করবে, অন্যরা কেবল একটি উইচার_আর উপাদান নিবে। সুতরাং যে উপস্থাপনাটি gnu সংকলক দ্বারা নির্মিত প্রতিনিধির সাথে সামঞ্জস্যপূর্ণ হবে না (যেখানে এফএফএফএফের চেয়ে কম সমস্ত অক্ষরের সামনে শূন্য শব্দ থাকবে)। Wchar_t এ যা সঞ্চয় রয়েছে তা প্রোগ্রামার এবং সংকলক দ্বারা নির্ধারিত হয়, কোনও চুক্তির দ্বারা নয়
সুইফট - শুক্রবার পাই
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.