একটি স্ট্রিং সি ++ এ আপার কেস রূপান্তর করুন


268

কিভাবে একটি স্ট্রিং আপার কেস রূপান্তর করতে পারে। গুগলিং থেকে আমি যে উদাহরণগুলি পেয়েছি তার মধ্যে কেবল চরগুলিই ডিল করতে হবে।

উত্তর:


205

স্ট্রিং অ্যালগোরিদম বুস্ট করুন:

#include <boost/algorithm/string.hpp>
#include <string>

std::string str = "Hello World";

boost::to_upper(str);

std::string newstr = boost::to_upper_copy<std::string>("Hello World");

5
এটির সাথে আই 18 এন এর সুবিধাও রয়েছে, যেখানে ::toupperসম্ভবত এটি এসসিআইআই অনুমান করা হয়।
বেন স্ট্রাব

4
আপনার শেষ লাইনটি সংকলন করে না - আপনাকে এমন কিছুতে পরিবর্তন করতে হবে:std::string newstr(boost::to_upper_copy<std::string>("Hello World"));
ম্যাক্সচ্লেপজিগ

58
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত নয় কারণ এটির উত্সাহ প্রয়োজন, বা শিরোনাম পরিবর্তন করা উচিত।
Andrea

44
হ্যাঁ, আমি কেবল টু_উপারের জন্য উত্সাহ ইনস্টল করতে চলেছি ... দুর্দান্ত ধারণা! </sarcasm> :)
থ্যাং করুন

12
"আমি সি ++ তে কীভাবে এক্স করব ?" এর জবাব হিসাবে আমি ব্যক্তিগতভাবে বৃদ্ধির প্রতি দুর্বল হয়ে পড়েছি ? কারণ বুস্ট মোটেই হালকা ওজনের সমাধান নয়। দেখে মনে হচ্ছে আপনি হয় একটি ফ্রেমওয়ার্ক হিসাবে (বা এসি বা কিউটি বা পুনরূদ্ধার সরঞ্জামকিট ++ বা ...) হিসাবে কিনেছেন বা আপনি তা করেন না। আমি ভাষার সমাধান দেখতে পছন্দ করি।
jwm

486
#include <algorithm>
#include <string>

std::string str = "Hello World";
std::transform(str.begin(), str.end(),str.begin(), ::toupper);

8
আসলে, toupper()ম্যাক্রো হিসাবে প্রয়োগ করা যেতে পারে। এটি কোনও সমস্যার কারণ হতে পারে।
সজাগভাবে

3
boost.lambda সহ একটি বাঁধাই (:: টুপার, <স্বাক্ষরিত চর>> __ 1)) পুরোপুরি সূক্ষ্মভাবে পরিবেশন করবে বলে আমি মনে করি।
জোহানেস স্কাউব -

11
এই পদ্ধতিটি ASCII এর জন্য দুর্দান্ত কাজ করে তবে একাধিক বাইট অক্ষর এনকোডিংগুলির জন্য বা জার্মান 'ß' এর মতো বিশেষ কেসিং বিধিগুলিতে ব্যর্থ হয়।
dan04

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

2
সংযোগকারীরা কেন আগে এই কোডটি ছাড়েনি: কেন আগে কোয়ালিফায়ার ছাড়া আমি পাই না toupper। কোন ধারনা?
sasha.sochka

89

সি ++ 11 এবং টুপার () ব্যবহার করে সংক্ষিপ্ত সমাধান।

for (auto & c: str) c = toupper(c);

টাইপ cহবে না const char(থেকে auto)? যদি তা হয় তবে আপনি এটিকে ( constঅংশের কারণে ) যা দিয়ে ফিরে আসবে তা নির্ধারণ করতে পারবেন না toupper(c)
পোলগ্রাফিক

5
@ পোলগ্রাফিক: ব্যাপ্তি - এর সামগ্রীতে পুনরাবৃত্তি করতে ধারকটির শুরু () / শেষ () পদ্ধতিগুলি ব্যবহারের জন্য ভিত্তি করে। std :: বেসিক_স্ট্রিংয়ে উভয়ই একটি কনস্ট এবং মিউটেবল পুনরাবৃত্তকারী রয়েছে (যথাক্রমে cbegin () দ্বারা আর্ট () এবং স্টার্ট (:) দিয়ে শুরু করুন , স্ট্যান্ডার্ড :: বেসিক_স্ট্রিং :: শুরু ) দেখুন, সুতরাং (:) জন্য একটি উপযুক্ত (সিবিগিন () ব্যবহার করা থাকলে অটো =: = কনস্ট চরের সাথে কনস্ট হিসাবে ঘোষিত, () অন্যথায়, অটো =: = চর দিয়ে) শুরু করুন।
থানাসিস পাপআউটসাইডাকিস

5
নীচে dirkgently এর anser দেখুন, এটি সংশোধন cকরার unsigned charজন্য কাস্ট করা প্রয়োজন।
ক্রিস লুয়েংগো

বুস্টের টু_পার () টিপারের চেয়ে সি ++ এসটিএল ফাংশনগুলির সাথে অনেক বেশি সুসংগত বলে মনে হচ্ছে।
tartaruga_casco_mole

29
struct convert {
   void operator()(char& c) { c = toupper((unsigned char)c); }
};

// ... 
string uc_str;
for_each(uc_str.begin(), uc_str.end(), convert());

দ্রষ্টব্য: শীর্ষ সমাধানের সাথে কয়েকটি সমস্যা:

21.5 নাল-টার্মিনেটেড সিকোয়েন্স ইউটিলিটিগুলি

এই শিরোলেখগুলির বিষয়বস্তু স্ট্যান্ডার্ড সি লাইব্রেরির শিরোনামগুলির মতো হবে <ctype.h>, <wctype.h>, <স্ট্রিং h>, <wchar.h>, এবং <stdlib.h> [...]

  • যার অর্থ এই যে cctypeসদস্যরা স্ট্যান্ডার্ড অ্যালগরিদমে সরাসরি ব্যবহারের জন্য উপযুক্ত নয়।

  • একই উদাহরণের সাথে আর একটি সমস্যা হ'ল এটি আর্গুমেন্টটি দেয় না বা যাচাই করে না যে এটি অ-নেতিবাচক; এটি সাদামাটা charস্বাক্ষরিত সিস্টেমগুলির জন্য বিশেষত বিপজ্জনক । (কারণ হ'ল: যদি এটি ম্যাক্রো হিসাবে প্রয়োগ করা হয় তবে এটি সম্ভবত একটি সারণীতে একটি সারণী এবং আপনার যুক্তি সূচি ব্যবহার করবে A নেতিবাচক সূচী আপনাকে ইউবি দেবে))


সাধারণ cctype সদস্যরা হ'ল ম্যাক্রোগুলি। আমার মনে আছে এটি পড়ার কথা মনে আছে যে তাদেরও ফাংশনগুলি করতে হয়েছিল, যদিও আমার কাছে সি 90 স্ট্যান্ডার্ডের একটি অনুলিপি নেই এবং আমি জানি না এটি স্পষ্টভাবে বলা হয়েছে কিনা not
ডেভিড থর্নলি

1
তাদের সি ++ এ ফাংশন করতে হবে - এমনকি সি তাদের ম্যাক্রো হওয়ার অনুমতি দেয়। আমি যদিও কাস্টিং সম্পর্কে আপনার দ্বিতীয় বিষয়টির সাথে একমত। শীর্ষ সমাধানটি নেতিবাচক মানগুলি পাস করতে পারে এবং এটির সাথে ইউবির কারণ হতে পারে। এই কারণেই আমি এটিকে ভোট
দিয়েছি

1
মানক উক্তিটি অবশ্যই অনুপস্থিত হবে না: 7.4.2.2/1 (দরিদ্র লিটব, এটি কেবলমাত্র C99 টিসি 2 খসড়াটি উল্লেখ করছে), এবং গ ++ + + 98 স্ট্যান্ডার্ডে সি ++ 17.4.1.2/6।
জোহানেস স্কাউব -

1
(এটিকে পাদ-নোটটি নোট করুন: "এটি একটি মাস্কিং ম্যাক্রো সরবরাহ করার প্রচলিত অভ্যাসটিকে অস্বীকার করে .... ব্লাহ ব্লুপ .. এটি সি ++ এ করার একমাত্র উপায় একটি বাহ্যিক ইনলাইন ফাংশন সরবরাহ করা" ") :)
জোহানেস শ্যাউব - lit 18

1
: ... যে এই কপট অর্জন হচ্ছে stackoverflow.com/questions/650461/...
litb - জোহানেস Schaub

27

এএসসিআইআই অক্ষর সেটটির জন্য এই সমস্যাটি সিমডের সাহায্যে ভেক্টরাইজযোগ্য


স্পিডআপ তুলনা:

-O3 -march=nativeএকটি কোর 2 ডিউও (মেরম) এ x86-64 গিসি 5.2 সহ প্রাথমিক পরীক্ষা করা । 120 অক্ষরের একই স্ট্রিং (মিশ্র লোয়ারकेস এবং নন-লোয়ারকেস এএসসিআইআই) 40M বারে লুপে রূপান্তরিত হয়েছে (কোনও ক্রস-ফাইল ইনলাইনিং সহ নয়, তাই সংকলকটি লুপের বাইরে অপ্টিমাইজ করতে বা এর কোনওটিকে উত্তোলন করতে পারে না)। একই উত্স এবং গন্তব্য বাফার, সুতরাং কোনও ম্যালোক ওভারহেড বা মেমরি / ক্যাশে প্রভাব নেই: পুরো সময় L1 ক্যাশে ডেটা গরম থাকে এবং আমরা খালি সিপিইউ-আবদ্ধ।

  • boost::to_upper_copy<char*, std::string>(): 198.0s । হ্যাঁ, উবুন্টু 15.10 এ 1.58 বুস্ট করা সত্যই এই ধীর। আমি একটি ডিবাগারে asm প্রফুল্ল করেছি এবং একক পদক্ষেপ নিয়েছি এবং এটি সত্যই, সত্যিই খারাপ: চরিত্র অনুসারে লোকাল ভেরিয়েবলের গতিশীল_কাস্ট রয়েছে !!! (ডায়নামিক_কাস্ট একাধিক কলকে স্ট্রম্পে ক্যাম্পে নিয়ে যায়)। এর সাথে LANG=Cও সাথে ঘটেLANG=en_CA.UTF-8

    আমি স্ট্যান্ড :: স্ট্রিং ব্যতীত অন্য কোনও রেঞ্জটি ব্যবহার করে পরীক্ষা করিনি। হতে পারে অন্য রূপটিto_upper_copy আরও ভালতর করতে পারে তবে আমি মনে করি এটি অনুলিপি new/ mallocঅনুলিপিটির জন্য সর্বদা স্থান থাকবে তাই এটি পরীক্ষা করা আরও কঠিন। হতে পারে আমি যা কিছু করেছি সেগুলি সাধারণ ব্যবহারের ক্ষেত্রে থেকে আলাদা হয় এবং সাধারণত বন্ধ হওয়া জি ++ প্রতি চরিত্রের লুপের বাইরে লোকাল সেটআপ স্টাফ উত্তোলন করতে পারে। আমার থেকে লুপ পড়া এবং একটি std::stringলেখার char dstbuf[4096]জন্য পরীক্ষার জন্য বোধগম্য।

  • লুপ কলিং গ্লিবসিtoupper : 6.67 এস ( intযদিও সম্ভাব্য মাল্টি-বাইট ইউটিএফ -8 এর ফলাফল পরীক্ষা করছে না , তুর্কিদের জন্য এটি গুরুত্বপূর্ণ matters)

  • কেবলমাত্র ASCII লুপ: 8.79s (নীচের ফলাফলের জন্য আমার বেসলাইন সংস্করণ)) স্পষ্টতই একটি টেবিল- লুক একটির চেয়ে দ্রুতcmov , যাইহোক L1 তে টেবিল গরম থাকে।
  • ASCII- কেবল অটো-ভেক্টরাইজড: 2.51 এস । (120 টি চরিত্রটি সবচেয়ে খারাপ ক্ষেত্রে এবং সর্বোত্তম মামলার মাঝামাঝি দিকের নীচে দেখুন)
  • ASCII- কেবল ম্যানুয়ালি ভেক্টরাইজড: 1.35 এস

যখন কোনও লোকেল সেট করা হয় তখন উইন্ডোতে ধীর হওয়া সম্পর্কে এই প্রশ্নটিtoupper() দেখুন ।


আমি হতবাক হয়ে গিয়েছিলাম যে বুস্টটি অন্যান্য বিকল্পগুলির চেয়ে ধীর গতির একটি ক্রম। আমি -O3সক্ষম হয়েছি কিনা ডাবল-চেক করেছিলাম এবং এমনকি এটি কী করছে তা দেখার জন্য এএসএমকে একক পদক্ষেপ দিয়েছিল। এটি ঝাঁকুনির সাথে প্রায় একই গতি ++ 3.8। প্রতি-চরিত্রের লুপের ভিতরে এটির বিশাল ওভারহেড রয়েছে। perf record/ reportফলাফলের (জন্য cyclesজন্য perf ঘটনা) হল:

  32.87%  flipcase-clang-  libstdc++.so.6.0.21   [.] _ZNK10__cxxabiv121__vmi_class_type_info12__do_dyncastElNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16
  21.90%  flipcase-clang-  libstdc++.so.6.0.21   [.] __dynamic_cast                                                                                                 
  16.06%  flipcase-clang-  libc-2.21.so          [.] __GI___strcmp_ssse3                                                                                            
   8.16%  flipcase-clang-  libstdc++.so.6.0.21   [.] _ZSt9use_facetISt5ctypeIcEERKT_RKSt6locale                                                                     
   7.84%  flipcase-clang-  flipcase-clang-boost  [.] _Z16strtoupper_boostPcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE                                   
   2.20%  flipcase-clang-  libstdc++.so.6.0.21   [.] strcmp@plt                                                                                                     
   2.15%  flipcase-clang-  libstdc++.so.6.0.21   [.] __dynamic_cast@plt                                                                                             
   2.14%  flipcase-clang-  libstdc++.so.6.0.21   [.] _ZNKSt6locale2id5_M_idEv                                                                                       
   2.11%  flipcase-clang-  libstdc++.so.6.0.21   [.] _ZNKSt6locale2id5_M_idEv@plt                                                                                   
   2.08%  flipcase-clang-  libstdc++.so.6.0.21   [.] _ZNKSt5ctypeIcE10do_toupperEc                                                                                  
   2.03%  flipcase-clang-  flipcase-clang-boost  [.] _ZSt9use_facetISt5ctypeIcEERKT_RKSt6locale@plt                                                                 
   0.08% ...

Autovectorization

যখন পুনরাবৃত্তির গণনাটি লুপের আগে জানা যায় তখনই জিসিসি এবং ক্ল্যাং কেবল লুপগুলিকে স্বয়ংক্রিয়-ভেক্টরাইজ করবে। (যেমন, এর সরল-সি প্রয়োগের মতো লুপগুলি অনুসন্ধান করুনstrlen স্বয়ংক্রিয়করণ করবে না))

সুতরাং, ক্যাশে ফিট করার জন্য পর্যাপ্ত ছোট স্ট্রিংগুলির জন্য, আমরা স্ট্রিংগুলির জন্য একটি গুরুত্বপূর্ণ স্পিডআপ পাই ~ 128 অক্ষর strlenপ্রথমে করা থেকে দীর্ঘ । সুস্পষ্ট দৈর্ঘ্যের স্ট্রিংগুলির জন্য এটি প্রয়োজন হবে না (যেমন সি ++ std::string)।

// char, not int, is essential: otherwise gcc unpacks to vectors of int!  Huge slowdown.
char ascii_toupper_char(char c) {
    return ('a' <= c && c <= 'z') ? c^0x20 : c;    // ^ autovectorizes to PXOR: runs on more ports than paddb
}

// gcc can only auto-vectorize loops when the number of iterations is known before the first iteration.  strlen gives us that
size_t strtoupper_autovec(char *dst, const char *src) {
    size_t len = strlen(src);
    for (size_t i=0 ; i<len ; ++i) {
        dst[i] = ascii_toupper_char(src[i]);  // gcc does the vector range check with psubusb / pcmpeqb instead of pcmpgtb
    }
    return len;
}

যে কোনও শালীন libc একটি দক্ষ হবে strlen এর যা একবারে বাইট লুপিংয়ের চেয়ে অনেক দ্রুত, তাই পৃথক ভেক্টরাইজড স্ট্রেন এবং টপার্প লুপগুলি দ্রুত।

বেসলাইন: একটি লুপ যা ফ্লাইতে 0 টি সমাপ্তির জন্য পরীক্ষা করে।

40M পুনরাবৃত্তির জন্য টাইমস, একটি কোর 2 (মেরম) 2.4GHz এ। জিসিসি 5.2 -O3 -march=native। (উবুন্টু 15.10)। dst != src(সুতরাং আমরা একটি অনুলিপি তৈরি করি), তবে সেগুলি ওভারল্যাপ করে না (এবং কাছাকাছি নয়)। দুটোই সারিবদ্ধ

  • 15 চর স্ট্রিং: বেসলাইন: 1.08 এস। অটোভেক: 1.34 এস
  • 16 চর স্ট্রিং: বেসলাইন: 1.16 গুলি। অটোভেক: 1.52 সে
  • 127 চর স্ট্রিং: বেসলাইন: 8.91s। অটোভেক: ২.৯৮ এস // নন-ভেক্টর ক্লিনআপ প্রক্রিয়া করার জন্য 15 টি অক্ষর রয়েছে
  • 128 চর স্ট্রিং: বেসলাইন: 9.00 এস। অটোভেক: ২.০6 এস
  • 129 চর স্ট্রিং: বেসলাইন: 9.04 এস। অটোভেক: ২.০7 এস // নন-ভেক্টর ক্লিনআপে প্রক্রিয়া করার জন্য 1 টি রয়েছে

কিছু ফলাফল ঝাঁকুনির সাথে কিছুটা আলাদা।

ফাংশনটি কল করে এমন মাইক্রোবেঞ্চমার্ক লুপটি একটি পৃথক ফাইলে রয়েছে। অন্যথায় এটি ইনলাইনস এবংstrlen() লুপ থেকে উত্তোলন হয়ে যায় এবং এটি নাটকীয়ভাবে দ্রুত চালিত হয়, esp। 16 চর স্ট্রিং (0.187s) এর জন্য।

এর বড় সুবিধাটি হ'ল যে কোনও আর্কিটেকচারের জন্য জিসিসি এটি স্বয়ংক্রিয়ভাবে ভেক্টরাইজ করতে পারে, তবে বড় অসুবিধাটি এটি ছোট স্ট্রিংয়ের সাধারণত-সাধারণ ক্ষেত্রে ধীর হয়।


সুতরাং এখানে বড় স্পিডআপ রয়েছে তবে সংকলক স্বয়ং-ভেক্টরাইজেশন দুর্দান্ত কোড তৈরি করে না, এসএসপি। শেষ পর্যন্ত 15 অক্ষর পরিষ্কার করার জন্য।

এসএসই অভ্যন্তরীণগুলির সাথে ম্যানুয়াল ভেক্টরাইজেশন:

আমার কেস-ফ্লিপ ফাংশনের ভিত্তিতে যা প্রতিটি বর্ণমালার চরিত্রের ক্ষেত্রে উল্টায়। এটি "স্বাক্ষরযুক্ত স্বীকৃতি তুলনা কৌশল" এর সুবিধা নেয়, যেখানে আপনি low < a && a <= highপরিসীমা স্থানান্তর করে একক স্বাক্ষরযুক্ত তুলনা না করে করতে পারেন , যাতে কোনও মানের চেয়ে বেশি যে lowমোড়কের চেয়ে কম হয় high। (এটি কাজ করে যদি lowএবংhigh খুব বেশী দূরে সরাইয়া হয় না।)

এসএসইতে কেবল একটি স্বাক্ষরিত তুলনা-বৃহত্তর রয়েছে, তবে আমরা এখনও স্বাক্ষরিত রেঞ্জের নীচে সীমা স্থানান্তর করে "স্বাক্ষরযুক্ত তুলনা" কৌশলটি ব্যবহার করতে পারি: 'এ' + 128 বিয়োগ করুন, সুতরাং বর্ণানুক্রমিক অক্ষরগুলি -128 থেকে -128 এর মধ্যে রয়েছে +25 (-128 + 'জেড' - 'এ')

মনে রাখবেন যে 128 যোগ করা এবং 128 বিয়োগ করা 8 বিট পূর্ণসংখ্যার জন্য একই জিনিস। বহন করার জন্য কোথাও নেই, সুতরাং এটি কেবলমাত্র জোর (বহনযোগ্য অ্যাড), উচ্চ বিটকে ফ্লিপ করে।

#include <immintrin.h>

__m128i upcase_si128(__m128i src) {
    // The above 2 paragraphs were comments here
    __m128i rangeshift = _mm_sub_epi8(src, _mm_set1_epi8('a'+128));
    __m128i nomodify   = _mm_cmpgt_epi8(rangeshift, _mm_set1_epi8(-128 + 25));  // 0:lower case   -1:anything else (upper case or non-alphabetic).  25 = 'z' - 'a'

    __m128i flip  = _mm_andnot_si128(nomodify, _mm_set1_epi8(0x20));            // 0x20:lcase    0:non-lcase

    // just mask the XOR-mask so elements are XORed with 0 instead of 0x20
    return          _mm_xor_si128(src, flip);
    // it's easier to xor with 0x20 or 0 than to AND with ~0x20 or 0xFF
}

একটি ভেক্টরের জন্য কাজ করে এমন ফাংশনটি দেওয়া, একটি সম্পূর্ণ স্ট্রিং প্রক্রিয়া করার জন্য আমরা এটিকে একটি লুপে কল করতে পারি। যেহেতু আমরা ইতিমধ্যে এসএসই 2 কে লক্ষ্য করছি, আমরা একই সাথে একটি ভেক্টরাইজড এন্ড-অফ-স্ট্রিং চেক করতে পারি।

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

পুরো স্ট্রিংটি 16 বি এর নিচে থাকা অবস্থায় এটি কেবল কার্যকর হয় না: এমনকি যখন dst=srcঅ-পারমাণবিক পঠন-সংশোধন-লিখন কিছু বাইটকে স্পর্শ না করার মতো জিনিস হয় না এবং বহুবিধিত কোডটি ভেঙে ফেলতে পারে।

আমাদের এটির জন্য একটি স্কেলার লুপ রয়েছে, এবং srcসারিবদ্ধ হওয়ার জন্যও । যেহেতু আমরা জানি না যে 0 টি সমাপ্তিটি কোথায় হবে, তাই থেকে একটি স্বাক্ষরবিহীন লোড srcপরবর্তী পৃষ্ঠায় এবং সেগফল্টে যেতে পারে। যদি আমাদের কোনও প্রান্তিক 16 বি অংশে কোনও বাইটের দরকার হয় তবে পুরো সারিবদ্ধ 16 বি অংশটি লোড করা সর্বদা নিরাপদ।

ফুল উৎস: একটি GitHub সারকথা মধ্যে

// FIXME: doesn't always copy the terminating 0.
// microbenchmarks are for this version of the code (with _mm_store in the loop, instead of storeu, for Merom).
size_t strtoupper_sse2(char *dst, const char *src_begin) {
    const char *src = src_begin;
    // scalar until the src pointer is aligned
    while ( (0xf & (uintptr_t)src) && *src ) {
        *(dst++) = ascii_toupper(*(src++));
    }

    if (!*src)
        return src - src_begin;

    // current position (p) is now 16B-aligned, and we're not at the end
    int zero_positions;
    do {
        __m128i sv = _mm_load_si128( (const __m128i*)src );
        // TODO: SSE4.2 PCMPISTRI or PCMPISTRM version to combine the lower-case and '\0' detection?

        __m128i nullcheck = _mm_cmpeq_epi8(_mm_setzero_si128(), sv);
        zero_positions = _mm_movemask_epi8(nullcheck);
        // TODO: unroll so the null-byte check takes less overhead
        if (zero_positions)
            break;

        __m128i upcased = upcase_si128(sv);   // doing this before the loop break lets gcc realize that the constants are still in registers for the unaligned cleanup version.  But it leads to more wasted insns in the early-out case

        _mm_storeu_si128((__m128i*)dst, upcased);
        //_mm_store_si128((__m128i*)dst, upcased);  // for testing on CPUs where storeu is slow
        src += 16;
        dst += 16;
    } while(1);

    // handle the last few bytes.  Options: scalar loop, masked store, or unaligned 16B.
    // rewriting some bytes beyond the end of the string would be easy,
    // but doing a non-atomic read-modify-write outside of the string is not safe.
    // Upcasing is idempotent, so unaligned potentially-overlapping is a good option.

    unsigned int cleanup_bytes = ffs(zero_positions) - 1;  // excluding the trailing null
    const char* last_byte = src + cleanup_bytes;  // points at the terminating '\0'

    // FIXME: copy the terminating 0 when we end at an aligned vector boundary
    // optionally special-case cleanup_bytes == 15: final aligned vector can be used.
    if (cleanup_bytes > 0) {
        if (last_byte - src_begin >= 16) {
            // if src==dest, this load overlaps with the last store:  store-forwarding stall.  Hopefully OOO execution hides it
            __m128i sv = _mm_loadu_si128( (const __m128i*)(last_byte-15) ); // includes the \0
            _mm_storeu_si128((__m128i*)(dst + cleanup_bytes - 15), upcase_si128(sv));
        } else {
            // whole string less than 16B
            // if this is common, try 64b or even 32b cleanup with movq / movd and upcase_si128
#if 1
            for (unsigned int i = 0 ; i <= cleanup_bytes ; ++i) {
                dst[i] = ascii_toupper(src[i]);
            }
#else
            // gcc stupidly auto-vectorizes this, resulting in huge code bloat, but no measurable slowdown because it never runs
            for (int i = cleanup_bytes - 1 ;  i >= 0 ; --i) {
                dst[i] = ascii_toupper(src[i]);
            }
#endif
        }
    }

    return last_byte - src_begin;
}

40M পুনরাবৃত্তির জন্য টাইমস, একটি কোর 2 (মেরম) 2.4GHz এ। জিসিসি 5.2 -O3 -march=native। (উবুন্টু 15.10)। dst != src(সুতরাং আমরা একটি অনুলিপি তৈরি করি), তবে সেগুলি ওভারল্যাপ করে না (এবং কাছাকাছি নয়)। দুটোই সারিবদ্ধ

  • 15 চর স্ট্রিং: বেসলাইন: 1.08 এস। অটোভেক: 1.34 এস। ম্যানুয়াল: 1.29s
  • 16 চর স্ট্রিং: বেসলাইন: 1.16 গুলি। অটোভেক: 1.52 সে। ম্যানুয়াল: 0.335s
  • 31 চর স্ট্রিং: ম্যানুয়াল: 0.479 এস
  • 127 চর স্ট্রিং: বেসলাইন: 8.91s। অটোভেক: ২.৯৮ এস। ম্যানুয়াল: 0.925s
  • 128 চর স্ট্রিং: বেসলাইন: 9.00 এস। অটোভেক: ২.০6 এস। ম্যানুয়াল: 0.931s
  • 129 চর স্ট্রিং: বেসলাইন: 9.04 এস। অটোভেক: ২.০7 এস। ম্যানুয়াল: 1.02 এস

(আসলে _mm_storeলুপের সাথে সময়সীমা _mm_storeuবেঁধে দেওয়া হয়নি , কারণ ঠিকানাটি সারিবদ্ধ হওয়ার পরেও মেরুতে স্টোরু ধীরে ধীরে Ne এটি নেহালেম এবং পরে ঠিক আছে copy অনুলিপি ঠিক করার পরিবর্তে আমি কোডটি এখনকার হিসাবে রেখেছি কিছু ক্ষেত্রে 0 সমাপ্তি, কারণ আমি সবকিছুকে পুনরায় সময় দিতে চাই না))

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

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

এমনকি ছোট স্ট্রিং জন্য ভেক্টর speedups সঙ্গে প্রাপ্ত করা যাবে movqবা movdলোড / দোকান। আপনার ব্যবহারের ক্ষেত্রে প্রয়োজন হিসাবে কাস্টমাইজ করুন।


হল UTF-8:

আমাদের ভেক্টরের যখন উচ্চ বিট সেট সহ কোনও বাইট থাকে তখন আমরা সনাক্ত করতে পারি এবং সেই ক্ষেত্রে সেই ভেক্টরের জন্য একটি স্কেলার utf-8-সচেতন লুপে ফিরে যেতে পারি। dstবিন্দু তুলনায় বিভিন্ন পরিমাণ দ্বারা আগাম পারেন srcপয়েন্টার, কিন্তু একবার আমরা ফিরে একটি প্রান্তিককৃত পেতে srcপয়েন্টার, আমরা এখনও ঠিক unaligned ভেক্টর দোকানে চেষ্টা করবো dst

UTF-8, তবে বেশিরভাগ UTF-8 এর ASCII উপসেট সমন্বিত পাঠ্যের জন্য, এটি ভাল হতে পারে: সব ক্ষেত্রে সঠিক আচরণের সাথে সাধারণ ক্ষেত্রে উচ্চ কার্যকারিতা। যখন অ-এএসসিআইআই প্রচুর আছে, সম্ভবত এটি সমস্ত সময় স্কেলারের ইউটিএফ -8 সচেতন লুপে থাকার চেয়ে আরও খারাপ হবে though

অন্যান্য ভাষার ব্যয়ে দ্রুত ইংরাজী করা ভবিষ্যতের প্রুফ সিদ্ধান্ত নয় যদি ডাউনসাইডটি তাৎপর্যপূর্ণ হয়।


লোকেল সচেতন:

তুর্কী লোকেলে ( tr_TR), থেকে সঠিক ফলাফলের toupper('i')হয় 'İ'(U0130), না 'I'(সাধারণ হওয়া ASCII)। উইন্ডোজটিতে ধীরগতির বিষয়ে একটি প্রশ্নে মার্টিন বোনারের মন্তব্য দেখুন tolower()

মাল্টি-বাইট ইউটিএফ 8 ইনপুট অক্ষরের মতো আমরা সেখানে স্কেলারের ব্যতিক্রম-তালিকা এবং ফলব্যাকের জন্যও পরীক্ষা করতে পারি।

এই অনেক জটিলতার সাথে, এসএসই 4.2 PCMPISTRMবা কোনও কিছু আমাদের চেকগুলি একসাথে করতে সক্ষম হতে পারে।


20

আপনার স্ট্রিং এএসসিআইআই বা আন্তর্জাতিক অক্ষর আছে?

যদি এটি পরবর্তী ক্ষেত্রে হয় তবে "বড় হাতের অক্ষর" এতটা সহজ নয়, এবং এটি ব্যবহৃত বর্ণমালার উপর নির্ভর করে। দ্বি দ্বিদলীয় এবং একতাত্ত্বিক বর্ণমালা রয়েছে। আপার এবং লোয়ার কেসগুলির জন্য কেবল দ্বিদলীয় বর্ণমালার আলাদা আলাদা অক্ষর রয়েছে। এছাড়াও, ল্যাটিন মূলধন 'ডিজেড' (\ u01F1 'ডিজেড') এর মতো সংমিশ্রিত অক্ষর রয়েছে যা তথাকথিত শিরোনাম কেস ব্যবহার করে । এর অর্থ হ'ল কেবল প্রথম অক্ষর (ডি) পরিবর্তিত হয়।

আমি আপনাকে আইসিইউতে সন্ধান করার পরামর্শ দিচ্ছি এবং সহজ এবং সম্পূর্ণ কেস ম্যাপিংয়ের মধ্যে পার্থক্য রাখছি । এটি সাহায্য করতে পারে:

http://userguide.icu-project.org/transforms/casemappings


7
বা জার্মান এসেট (এসপি?), এমন জিনিস যা গ্রীক বর্ণ বিটার মতো লাগে এবং এর অর্থ "এসএস"। জার্মানির কোনও একক অক্ষর নেই যার অর্থ "এসএস", যা বড় হাতের সমতুল্য। "রাস্তার" জন্য জার্মান শব্দটি যখন বড়হীন হয়, তখন একটি চরিত্র দীর্ঘ হয়।
ডেভিড থর্নলি

6
আর একটি বিশেষ কেস হ'ল গ্রীক অক্ষর সিগমা (Σ), যার দুটি ছোট অক্ষর রয়েছে, এটি কোনও শব্দের শেষে (ς) না হয় (σ) এর উপর নির্ভর করে। এবং তারপরে ভাষা নির্দিষ্ট নিয়ম রয়েছে, যেমন তুর্কি আই কে এবং আইআই কে ম্যাপিং করে।
dan04

1
"বড়হাঁস" কে কেস ফোল্ডিং বলা হয়।
কলম্বো

20
string StringToUpper(string strToConvert)
{
   for (std::string::iterator p = strToConvert.begin(); strToConvert.end() != p; ++p)
       *p = toupper(*p);

   return p;
}

অথবা,

string StringToUpper(string strToConvert)
{
    std::transform(strToConvert.begin(), strToConvert.end(), strToConvert.begin(), ::toupper);

    return strToConvert;
}

4
আপনার যদি দ্বিতীয় সমাধানটি বাড়ানোর অ্যাক্সেস না পান তবে সম্ভবত আপনি সবচেয়ে ভাল পেতে পারেন। **প্রথম সমাধানের প্যারামিটারগুলির পরে তারাগুলি কী করে?
স্যাম ব্রিন্ক

1
আমি নিশ্চিত **যে কোড টাইপটিতে বোল্ড ফন্ট ব্যবহার করার চেষ্টা করা থেকে বিরত একটি টাইপো রয়ে গেছে।
এইচডি

1
যখন এই toupperনেতিবাচক সংখ্যার সাথে ডাকা হয় তখন এই কোডটি অনির্ধারিত আচরণের ডাক দেয়।
রোল্যান্ড ইলিগ 21

17

নিম্নলিখিত আমার জন্য কাজ করে।

#include <algorithm>
void  toUpperCase(std::string& str)
{
    std::transform(str.begin(), str.end(), str.begin(), ::toupper);
}

int main()
{
   std::string str = "hello";
   toUpperCase(&str);
}

নোট করুন যে স্টাড :: ট্রান্সফর্মটি <algorithm>
এডজ

হ্যাঁ. এই # টি অন্তর্ভুক্ত করা দরকার, # অন্তর্ভুক্ত <আলগোরিদিম>
পবিত্র দাশ

1
যখন এই toupperনেতিবাচক সংখ্যার সাথে ডাকা হয় তখন এই কোডটি অনির্ধারিত আচরণের ডাক দেয়।
রোল্যান্ড ইলিগ 21

user648545 কর্তৃক প্রদত্ত উত্তরের প্রতিলিপি - -1
পাযত্র Dobrogost

@ পাইওটারডব্রোগস্ট ইউজার 648545 এর দেওয়া উত্তর সম্পর্কে আমার কোনও ধারণা নেই। আমি এটি অনুলিপি করি নি W যখন আমি দুটি পদ্ধতির তুলনা করি তবে পদ্ধতি স্বাক্ষর সম্পূর্ণ আলাদা হয় যদিও উভয় ফাংশন লাইব্রেরির ফাংশন রূপান্তর করে।
পবিত্র দাশ

13

একটি ল্যাম্বডা ব্যবহার করুন।

std::string s("change my case");

auto to_upper = [] (char_t ch) { return std::use_facet<std::ctype<char_t>>(std::locale()).toupper(ch); };

std::transform(s.begin(), s.end(), s.begin(), to_upper);

2
বায়রন, অন্যান্য মন্তব্য সম্পর্কে চিন্তা করবেন না। পুরানো প্রশ্নের উত্তর নতুন (আধুনিক) সমাধান হিসাবে আপনি যেমন দিয়েছিলেন ঠিক তেমন ঠিক।
কিবেরিয়াস

13

আপনি যদি কেবলমাত্র এসসিআইআই অক্ষর ব্যবহার করেন তবে দ্রুততর :

for(i=0;str[i]!=0;i++)
  if(str[i]<='z' && str[i]>='a')
    str[i]-=32;

দয়া করে নোট করুন যে এই কোডটি দ্রুত চালিত হয় তবে কেবল ASCII এ কাজ করে এবং এটি একটি "বিমূর্ত" সমাধান নয়।

আপনার যদি ইউনিকোড সমাধান বা আরও প্রচলিত এবং বিমূর্ত সমাধানের প্রয়োজন হয় তবে অন্যান্য উত্তরের জন্য যান এবং সি ++ স্ট্রিংয়ের পদ্ধতিতে কাজ করুন।


1
প্রশ্নটি ট্যাগ হিসাবে রয়েছে C++তবে আপনি Cএখানে একটি উত্তর লিখেছিলেন । (আমি
নিম্নচাচকারীদের

6
আমি একটি সি উত্তর লিখেছিলাম এবং একটি সি ++ উত্তর এখানে বিচিউস সি ++ সি উত্সের সাথে পুরোপুরি সামঞ্জস্যপূর্ণ বলে লেখা হয়েছে, সুতরাং যে কোনও সি সমাধানটিও একটি সি ++ সঠিক সমাধান
লুকা সি

তবে এমন উত্তর দেওয়া আরও ভাল যা সি ++ উপায়কে সম্মান করে।
দিমিত্রি ইয়ুরচেঙ্কো

স্ট্যান্ডার্ড সি ++ উপায়টি হ'ল স্টাডি :: টুপারের সাথে রূপান্তরিত করুন। এটি কম কোড এবং নিশ্চিত পোর্টেবলের জন্য। এই কোডটি "সত্য" এর উপর নির্ভর করে যে সিস্টেমটি অক্ষর এনকোডিং প্রক্রিয়া হিসাবে ascii ব্যবহার করবে। নিশ্চিত নয় যে সমস্ত সিস্টেম এই এনকোডিংয়ের উপর ভিত্তি করে এবং সুতরাং এটি নিশ্চিত নয় যে এটি পোর্টেবল।
অ্যালেক্স থিও

1
আপনি কেন আবদ্ধ অক্ষরের পরিবর্তে ASCII কোড ব্যবহার করার সিদ্ধান্ত নিয়েছেন '?
হলিব্ল্যাকগেট

11

যতক্ষণ না আপনি কেবলমাত্র ASCII- এর সাথে ভাল থাকেন এবং আপনি আরডাব্লু মেমরির জন্য একটি বৈধ পয়েন্টার সরবরাহ করতে পারেন, সিতে একটি সহজ এবং খুব কার্যকর ওয়ান-লাইনার রয়েছে:

void strtoupper(char* str)
{ 
    while (*str) *(str++) = toupper((unsigned char)*str);
}

এটি ASCII শনাক্তকারীদের মতো সাধারণ স্ট্রিংগুলির জন্য বিশেষত ভাল যা আপনি একই চরিত্রের ক্ষেত্রে স্বাভাবিক করতে চান। তারপরে আপনি স্টাফ: স্ট্রিংয়ের উদাহরণটি তৈরি করতে বাফারটি ব্যবহার করতে পারেন।


একটি নোট করে যে এই উত্তরটি
এসডি

এটিতে একটি স্পষ্ট সহজাত সুরক্ষা ত্রুটি রয়েছে। আমি এই কাজ না।
বায়রন

9
//works for ASCII -- no clear advantage over what is already posted...

std::string toupper(const std::string & s)
{
    std::string ret(s.size(), char());
    for(unsigned int i = 0; i < s.size(); ++i)
        ret[i] = (s[i] <= 'z' && s[i] >= 'a') ? s[i]-('a'-'A') : s[i];
    return ret;
}

s.size () প্রকারের std ::
আকার_t এর যা এএফআইকে

আমি মনে করি না যে কোনও আধুনিক বাস্তবায়ন আছে যেখানে স্ট্যান্ড :: স্ট্রিং :: আকারের ফলাফল স্বাক্ষরিত হয়েছে। দেওয়া হয়েছে, শব্দার্থক ও ব্যবহারিকভাবে উভয়ই, নেতিবাচক আকারের মতো কোনও জিনিস নেই, আমি সাইজ_টাকে কমপক্ষে 32-বিট স্বাক্ষরযুক্ত পূর্ণসংখ্য হিসাবে যেতে যাচ্ছি।
ব্যবহারকারী 1329482

না লেখার কোনও কারণ নেই for (size_t i = 0 ...। এটি পড়া এত কঠিন করার কোনও ভাল কারণ নেই। এটি প্রথমে স্ট্রিংটি অনুলিপি করে তারপরে লুপ করে। @ লুকের উত্তর 'a'চরিত্রের ধ্রুবকগুলির সুবিধা না নেওয়া ব্যতীত কিছু উপায়ে আরও ভাল ।
পিটার কর্ডেস

9
#include <string>
#include <locale>

std::string str = "Hello World!";
auto & f = std::use_facet<std::ctype<char>>(std::locale());
f.toupper(str.data(), str.data() + str.size());

এটি গ্লোবাল টুপার ফাংশন ব্যবহার করে এমন সমস্ত উত্তরের চেয়ে আরও ভাল পারফরম্যান্স করবে এবং সম্ভবত: টু_পারটি নীচে যা করছে তা বাড়িয়ে তুলবে।

এটি কারণ: :: টুপারকে লোকেলটি সন্ধান করতে হবে - কারণ এটি একটি ভিন্ন থ্রেড দ্বারা পরিবর্তিত হতে পারে - প্রতিটি অনুরোধের জন্য, যদিও এখানে কেবল লোকালে () কল করার জন্য এই শাস্তি রয়েছে। এবং লোকেল সন্ধানের মধ্যে সাধারণত একটি লক নেওয়া জড়িত।

আপনি অটো প্রতিস্থাপন করার পরে, নতুন অ-কনস্ট্রেন্ট স্ট্রিংডাটা () ব্যবহার করে এবং টেমপ্লেটটি বন্ধ করার জন্য ""> ">>") এর মতো স্থান যুক্ত করার পরে এটি সি ++ 98 এর সাথেও কাজ করে:

std::use_facet<std::ctype<char> > & f = 
    std::use_facet<std::ctype<char> >(std::locale());
f.toupper(const_cast<char *>(str.data()), str.data() + str.size());

7
typedef std::string::value_type char_t;

char_t up_char( char_t ch )
{
    return std::use_facet< std::ctype< char_t > >( std::locale() ).toupper( ch );
}

std::string toupper( const std::string &src )
{
    std::string result;
    std::transform( src.begin(), src.end(), std::back_inserter( result ), up_char );
    return result;
}

const std::string src  = "test test TEST";

std::cout << toupper( src );

আপনি ইতিমধ্যে দৈর্ঘ্য জানেন হিসাবে একটি back_inserter সুপারিশ করবে; std :: স্ট্রিং ফলাফল (src.size ()) ব্যবহার করুন; std :: রূপান্তর (src.begin (), src.end (), ফলাফল.begin (), up_char);
ভিক্টর সেহর

যথেষ্ট হলেও আমি নিশ্চিত যে আপনি এটি জানেন।
ভিক্টর সেহর

@ ভিক্টর সেহর, @ বেদা: আমি জানি এটি 2 বছরের পুরনো, তবে কেন উভয় বিশ্বের সেরা পাওয়া যায় না। ব্যবহার করুন reserveএবং back_inserter(সুতরাং তৈরি করে স্ট্রিংটি কেবল একবার কপি করা হয়েছে)। inline std::string to_lower(const std::string &s) { std::string result; result.reserve(s.size()); std::transform(s.begin(), s.end(), std::back_inserter( result ), static_cast<int(*)(int)>(std::tolower)); return result; }
ইভান তেরান


2

toupper()ফাংশন চেষ্টা করুন ( #include <ctype.h>)। এটি অক্ষরগুলি আর্গুমেন্ট হিসাবে গ্রহণ করে, স্ট্রিংগুলি অক্ষর দ্বারা গঠিত হয়, সুতরাং আপনাকে প্রতিটি স্বতন্ত্র চরিত্রের উপরে পুনরাবৃত্তি করতে হবে যা যখন একসাথে স্ট্রিংকে অন্তর্ভুক্ত করে


যখন এই toupperনেতিবাচক সংখ্যার সাথে ডাকা হয় তখন এই পরামর্শটি অনির্ধারিত আচরণের ডাক দেয়। আপনার প্রয়োজনীয় কাস্টের উল্লেখ করা উচিত ছিল unsigned char
রোল্যান্ড ইলিগ 21

2

সি ++ 11 সহ সর্বশেষ কোডটি এখানে

std::string cmd = "Hello World";
for_each(cmd.begin(), cmd.end(), [](char& in){ in = ::toupper(in); });

Codeণাত্মক toupperসংখ্যার সাথে ডাকা হলে এই কোডটি অনির্ধারিত আচরণের ডাক দেয়।
রোল্যান্ড ইলিগ 21

1

বুস্ট.টেক্সট ব্যবহার করে, যা ইউনিকোড পাঠ্যের জন্য কাজ করবে

boost::text::text t = "Hello World";
boost::text::text uppered;
boost::text::to_title(t, std::inserter(uppered, uppered.end()));
std::string newstr = uppered.extract();

1

উত্তর এর @dirkgently খুব দীপক হয়, কিন্তু আমি যে জোর উদ্বেগ কারণে যেমন নিম্নে দেখানো হল চাই,

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

এর সঠিক ব্যবহারটি হওয়া std::toupperউচিত:

#include <algorithm>
#include <cctype>
#include <iostream>
#include <iterator>
#include <string>

void ToUpper(std::string& input)
{
    std::for_each(std::begin(input), std::end(input), [](char& c) {
        c = static_cast<char>(std::toupper(static_cast<unsigned char>(c)));
    });
}

int main()
{
    std::string s{ "Hello world!" };
    std::cout << s << std::endl;
    ::ToUpper(s);
    std::cout << s << std::endl;

    return 0;
}

আউটপুট:

Hello world!
HELLO WORLD!

0

নিশ্চিত নেই যে সেখানে কোনও বিল্ট ইন ফাংশন রয়েছে। এটা চেষ্টা কর:

প্রাকপ্রসেসর নির্দেশের অংশ হিসাবে ctype.h বা cctype গ্রন্থাগারগুলির পাশাপাশি stdlib.h অন্তর্ভুক্ত করুন।

string StringToUpper(string strToConvert)
{//change each element of the string to upper case
   for(unsigned int i=0;i<strToConvert.length();i++)
   {
      strToConvert[i] = toupper(strToConvert[i]);
   }
   return strToConvert;//return the converted string
}

string StringToLower(string strToConvert)
{//change each element of the string to lower case
   for(unsigned int i=0;i<strToConvert.length();i++)
   {
      strToConvert[i] = tolower(strToConvert[i]);
   }
   return strToConvert;//return the converted string
}

.length () টাইপ 'স্বাক্ষরবিহীন int- এ' নয়
malat

Codeণাত্মক toupperসংখ্যার সাথে ডাকা হলে এই কোডটি অনির্ধারিত আচরণের ডাক দেয়।
রোল্যান্ড ইলিগ 21

0

আমার সমাধান (আলফার জন্য 6th ষ্ঠ বিট সাফ করা):

#include <ctype.h>

inline void toupper(char* str)
{
    while (str[i]) {
        if (islower(str[i]))
            str[i] &= ~32; // Clear bit 6 as it is what differs (32) between Upper and Lowercases
        i++;
    }
}

Codeণাত্মক toupperসংখ্যার সাথে ডাকা হলে এই কোডটি অনির্ধারিত আচরণের ডাক দেয়।
রোল্যান্ড ইলিগ 21

না ... দয়া করে ডাউনটাটিংয়ের আগে ঠিক আছে কিনা তা পরীক্ষা করে দেখুন। ইসলোয়ার কেবল অ নেতিবাচক মানগুলিতেই কাজ করবে ...
আন্তোনিন গ্যাভ্রিল

-1

এই পৃষ্ঠাগুলির এই সমস্ত সমাধানগুলির প্রয়োজনের তুলনায় আরও শক্ত।

এটা কর

RegName = "SomE StRing That you wAnt ConvErTed";
NameLength = RegName.Size();
for (int forLoop = 0; forLoop < NameLength; ++forLoop)
{
     RegName[forLoop] = tolower(RegName[forLoop]);
}

RegNameআপনার হয় string। আপনার স্ট্রিং আকারটি string.size()আপনার প্রকৃত পরীক্ষক হিসাবে ব্যবহার করবেন না , খুব অগোছালো এবং সমস্যার কারণ হতে পারে। তারপর। সবচেয়ে বেসিক forলুপ।

মনে রাখবেন স্ট্রিং সাইজ ডিলিমিটারকেও খুব বেশি দেয় তাই আপনার লুপ পরীক্ষায় <এবং না <= ব্যবহার করুন।

আউটপুটটি হবে: এমন কিছু স্ট্রিং যা আপনি রূপান্তর করতে চান


4
বুস্ট :: টুপার সমাধানের চেয়ে এটি কীভাবে সহজ তা আমি দেখছি না। তুমি কি বিস্তারিত বলতে পারো?
tr9sh

2
ইতিমধ্যে প্রচুর সরল tolowerলুপ রয়েছে এবং তাদের বেশিরভাগ স্ট্যান্ডার্ড লুপ ভেরিয়েবলের নাম ব্যবহার iকরে, অদ্ভুত নয় forLoop
পিটার কর্ডেস

-1

কোনও লাইব্রেরি ব্যবহার না করে:

std::string YourClass::Uppercase(const std::string & Text)
{
    std::string UppperCaseString;
    UppperCaseString.reserve(Text.size());
    for (std::string::const_iterator it=Text.begin(); it<Text.end(); ++it)
    {
        UppperCaseString.push_back(((0x60 < *it) && (*it < 0x7B)) ? (*it - static_cast<char>(0x20)) : *it);
    }
    return UppperCaseString;
}

উপরের কোডটি কেবল ASCII- সামঞ্জস্যপূর্ণ এনকোডিংয়ের জন্য কাজ করে। আপনার উত্তর নয় প্রশ্নটিতেও এই সীমাবদ্ধতার উল্লেখ নেই। তাদের একটি করা উচিত।
রোল্যান্ড ইলিগ 21

-1

আপনি যদি কেবল 8 টি বিট চরিত্রের সাথে সম্পর্কিত হন (যা মিলান বাবুস্কভ বাদে অন্য সমস্ত উত্তরও ধরে নেয়) আপনি রূপক ব্যবহার করে সংকলনের সময় একটি লক-আপ টেবিল তৈরি করে দ্রুত গতি পেতে পারেন। আইডোন.কম এ লাইব্রেরি ফাংশনের চেয়ে 7x দ্রুত এবং একটি হাতের লিখিত সংস্করণ ( http://ideone.com/sb1Rup ) এর চেয়ে 3x দ্রুত চলে । এটি কোনও ধীরগতি না দিয়ে বৈশিষ্ট্যের মাধ্যমেও কাস্টমাইজযোগ্য।

template<int ...Is>
struct IntVector{
using Type = IntVector<Is...>;
};

template<typename T_Vector, int I_New>
struct PushFront;
template<int ...Is, int I_New>
struct PushFront<IntVector<Is...>,I_New> : IntVector<I_New,Is...>{};

template<int I_Size, typename T_Vector = IntVector<>>
struct Iota : Iota< I_Size-1, typename PushFront<T_Vector,I_Size-1>::Type> {};
template<typename T_Vector>
struct Iota<0,T_Vector> : T_Vector{};

template<char C_In>
struct ToUpperTraits {
    enum { value = (C_In >= 'a' && C_In <='z') ? C_In - ('a'-'A'):C_In };
};

template<typename T>
struct TableToUpper;
template<int ...Is>
struct TableToUpper<IntVector<Is...>>{
    static char at(const char in){
        static const char table[] = {ToUpperTraits<Is>::value...};
        return table[in];
    }
};

int tableToUpper(const char c){
    using Table = TableToUpper<typename Iota<256>::Type>;
    return Table::at(c);
}

ব্যবহার ক্ষেত্রে:

std::transform(in.begin(),in.end(),out.begin(),tableToUpper);

এটি কীভাবে কাজ করে তার গভীরতার (বহু পৃষ্ঠার) ডিক্রিপশনের জন্য আমাকে নির্লজ্জভাবে আমার ব্লগটি প্লাগ করতে দেয়: http://metaporky.blogspot.de/2014/07/part-4-generating-look-up-tables-at.html


-1
template<size_t size>
char* toupper(char (&dst)[size], const char* src) {
    // generate mapping table once
    static char maptable[256];
    static bool mapped;
    if (!mapped) {
        for (char c = 0; c < 256; c++) {
            if (c >= 'a' && c <= 'z')
                maptable[c] = c & 0xdf;
            else
                maptable[c] = c;
        }
        mapped = true;
    }

    // use mapping table to quickly transform text
    for (int i = 0; *src && i < size; i++) {
        dst[i] = maptable[*(src++)];
    }
    return dst;
}

-1

এই সি ++ ফাংশন সর্বদা বড় হাতের অক্ষরে ফিরে আসে ...

#include <locale> 
#include <string>
using namespace std; 
string toUpper (string str){
    locale loc; 
    string n; 
    for (string::size_type i=0; i<str.length(); ++i)
        n += toupper(str[i], loc);
    return n;
}

-3

আমি এই সমাধানটি ব্যবহার করি। আমি জানি যে আপনি সেই ডেটা অঞ্চলটি পরিবর্তন করার কথা বলছেন না .... তবে আমি মনে করি এটি বেশিরভাগ বাফার ওভাররন বাগ এবং নাল চরিত্রের জন্য .... উপরের কেসিং জিনিসগুলি একই নয়।

void to_upper(const std::string str) {
    std::string::iterator it;
    int i;
    for ( i=0;i<str.size();++i ) {
        ((char *)(void *)str.data())[i]=toupper(((char *)str.data())[i]);
    }
}

I know you're not supposed to modify that data area- কোন ডেটা অঞ্চলটি আপনার পরিবর্তন করার কথা নয়?
user93353

3
এই দেরী, কিন্তু পৃথিবীতে কি? এই ক্রেজি লাইনটি str[i] = toupper(str[i]);পুরোপুরি সূক্ষ্ম দ্বারা প্রতিস্থাপিত করা যেতে পারে (ভাল, পুরোপুরি সূক্ষ্ম নয়, তবে এটি বেশিরভাগ ক্ষেত্রেই ভুলকে সংশোধন করে)।
ক্রিস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.