TL; ড
আইসিইউ লাইব্রেরি ব্যবহার করুন । আপনি যদি তা না করেন তবে আপনার রূপান্তর রুটিনটি এমন নীতিগুলির সাথে নীরবে ভেঙে যাবে আপনি সম্ভবত বিদ্যমান সম্পর্কে অবগত নন।
প্রথমে আপনাকে একটি প্রশ্নের উত্তর দিতে হবে: আপনার এনকোডিংটি কী std::string
? এটি কি আইএসও -8859-1? অথবা সম্ভবত আইএসও -8859-8? নাকি উইন্ডোজ কোডপেজ 1252? আপনি উপরের থেকে লোকেসকে রূপান্তর করতে যা ব্যবহার করছেন তা কি জানেন? (বা এটি চরিত্রগুলির জন্য খারাপভাবে ব্যর্থ হয়েছে 0x7f
?)
আপনি যদি std::string
কনটেইনার হিসাবে ইউটিএফ -8 (8-বিট এনকোডিংগুলির মধ্যে একমাত্র বুদ্ধিমান পছন্দ) ব্যবহার করে থাকেন তবে আপনি ইতিমধ্যে নিজেকে এমন কোনও নিয়ন্ত্রণে রাখছেন তা বিশ্বাস করে নিজেকে ফাঁকি দিচ্ছেন, কারণ আপনি কোনও ধারকটিতে মাল্টিবাইট চরিত্রের ক্রমটি সংরক্ষণ করছেন are এটি মাল্টিবাইট ধারণা সম্পর্কে অবগত নয়। এমনকি সহজ কিছু এমনকি .substr()
একটি টিকিং সময়স্রোত। (কারণ একটি মাল্টবাইট সিকোয়েন্স বিভক্ত করার ফলে একটি অবৈধ (উপ-) স্ট্রিং হবে)
এবং যত তাড়াতাড়ি আপনার মত কিছু করার চেষ্টা করুন std::toupper( 'ß' )
, এ কোন এনকোডিং, আপনি গভীর কষ্ট হয়। (কারণ স্ট্যান্ডার্ড লাইব্রেরি দিয়ে এই "সঠিক" করা সহজভাবে সম্ভব নয়, যা কেবল এখানে প্রয়োজনীয় ফলাফল নয় কেবল একটি ফলাফলের অক্ষর সরবরাহ করতে পারে "SS"
)) [1] আরেকটি উদাহরণ হতে পারে std::tolower( 'I' )
, যা লোকেলের উপর নির্ভর করে বিভিন্ন ফলাফল অর্জন করবে । জার্মানিতে, 'i'
সঠিক হবে; তুরস্কে, 'ı'
(ল্যাটিন ছোট ছোট ডটলস আই) প্রত্যাশিত ফলাফল (যা আবার ইউটিএফ -8 এনকোডিংয়ে এক বাইটের বেশি)। তবুও আরেকটি উদাহরণ হ'ল গ্রীক সিগমা , বড় '∑'
হাতের অক্ষর , ছোট হাতের অক্ষর 'σ'
... একটি শব্দের শেষে বাদে যেখানে এটি রয়েছে 'ς'
।
সুতরাং, যে কোনও ক্ষেত্রে রূপান্তর যা একবারে কোনও চরিত্রের উপরে কাজ করে বা আরও খারাপ, একবারে বাইট , ডিজাইন দ্বারা ভেঙে যায়।
তারপরে বিন্দুটি রয়েছে যে স্ট্যান্ডার্ড লাইব্রেরি, এটি করতে সক্ষম তার উপর নির্ভর করে আপনার সফ্টওয়্যারটি যে মেশিনে চলছে সেটিতে কোন লোকেলগুলি সমর্থনযোগ্য তা নির্ভর করে ... এবং যদি তা না হয় তবে আপনি কী করবেন?
তাই কি আপনি হয় সত্যিই খুঁজছেন একটি স্ট্রিং বর্গ যে সব এই সঙ্গে সঠিকভাবে আচরণ করতে সক্ষম হয়, এবং সেটা হল না কোন std::basic_string<>
রূপের ।
(সি ++ 11 নোট: std::u16string
এবং std::u32string
হয় ভাল ।, কিন্তু এখনও নিখুঁত নয় সি ++ 20 আনা std::u8string
, কিন্তু এই সব করতে এনকোডিং উল্লেখ অনেক অন্যান্য ক্ষেত্রেই তারা এখনও ইউনিকোড বলবিজ্ঞান অজ্ঞ থাকা, নিয়মমাফিককরণ, কোলেশন মতো ..। ।)
বুস্ট যদিও দেখায় জ্ঞানী সুন্দর এপিআই, Boost.Locale মূলত কাছাকাছি একটি লেফাফা হয় আইসিইউ । তাহলে বুস্ট হয় কম্পাইল আইসিইউ সমর্থনে ... যদি তা না হয়, Boost.Locale লোকেল সমর্থন মান লাইব্রেরির জন্য কম্পাইল সীমাবদ্ধ।
এবং আমার বিশ্বাস, পেয়ে সঙ্গে আইসিইউ একটি বাস্তব ব্যথা কখনো কখনো হতে পারে কম্পাইল করার বুস্ট। (উইন্ডোজের জন্য কোনও পূর্ব-সংকলিত বাইনারি নেই, সুতরাং আপনার অ্যাপ্লিকেশনের সাথে আপনার সেগুলি সরবরাহ করতে হবে এবং এটি পোকার সম্পূর্ণ নতুন ক্যান খুলবে ...)
সুতরাং ব্যক্তিগতভাবে আমি ঘোড়ার মুখ থেকে সরাসরি ইউনিকোড সমর্থন এবং আইসিইউ লাইব্রেরি সরাসরি ব্যবহার করার পরামর্শ দেব :
#include <unicode/unistr.h>
#include <unicode/ustream.h>
#include <unicode/locid.h>
#include <iostream>
int main()
{
/* "Odysseus" */
char const * someString = u8"ΟΔΥΣΣΕΥΣ";
icu::UnicodeString someUString( someString, "UTF-8" );
// Setting the locale explicitly here for completeness.
// Usually you would use the user-specified system locale,
// which *does* make a difference (see ı vs. i above).
std::cout << someUString.toLower( "el_GR" ) << "\n";
std::cout << someUString.toUpper( "el_GR" ) << "\n";
return 0;
}
সংকলন (এই উদাহরণে জি ++ সহ):
g++ -Wall example.cpp -licuuc -licuio
এটি দেয়:
ὀδυσσεύς
নোট করুন যে শব্দের মাঝখানে Σ <->। রূপান্তরকরণ এবং শব্দের শেষে-<->। রূপান্তর। কোনও <algorithm>
ভিত্তিযুক্ত সমাধান আপনাকে তা দিতে পারে না।
[1] 2017 সালে, জার্মান অর্থোগ্রাফির কাউন্সিল রায় দিয়েছে যে "ẞ" U + 1E9E ল্যাটিন ক্যাপিটাল লেটার শর্ট এস সরকারীভাবে ব্যবহার করা যেতে পারে, যেমন পাসপোর্টগুলিতে অস্পষ্টতা এড়াতে "এসএস" রূপান্তরের পাশাপাশি বিকল্প হিসাবে (যেখানে নাম মূলধনযুক্ত) )। আমার সুন্দর নজরে উদাহরণস্বরূপ, কমিটির সিদ্ধান্ত দ্বারা অপ্রচলিত ...