C++
std :: स्ट्रिंग
खोज…
परिचय
स्ट्रिंग्स ऑब्जेक्ट्स हैं जो वर्णों के अनुक्रम का प्रतिनिधित्व करते हैं। मानक string
कक्षा पाठ और वर्णों के अन्य अनुक्रमों से निपटने के दौरान char
s के स्पष्ट सरणियों का उपयोग करने के लिए एक सरल, सुरक्षित और बहुमुखी विकल्प प्रदान करता है। C ++ string
क्लास std
नाम स्थान का हिस्सा है और इसे 1998 में मानकीकृत किया गया था।
वाक्य - विन्यास
// खाली स्ट्रिंग घोषणा
std :: string s;
// कास्ट चार से निर्माण * (सी-स्ट्रिंग)
std :: string s ("हैलो");
std :: string s = "हैलो";
// कॉपी कंस्ट्रक्टर का उपयोग करके निर्माण करना
std :: string s1 ("हैलो");
std :: string s2 (s1);
// प्रतिस्थापन से निर्माण
std :: string s1 ("हैलो");
std :: string s2 (s1, 0, 4); // s2 में s1 की स्थिति 0 से 4 वर्णों की प्रतिलिपि बनाएँ
// वर्णों के एक बफर से निर्माण
std :: string s1 ("हैलो वर्ल्ड");
std :: string s2 (s1, 5); // s2 में s1 के पहले 5 अक्षरों को कॉपी करें// फिल कंस्ट्रक्टर (केवल चार) का उपयोग करके निर्माण
std :: string s (5, 'a'); // s में aaaaa शामिल है
// कंस्ट्रक्टर और इटरेटर का उपयोग करके निर्माण
std :: string s1 ("हैलो वर्ल्ड");
std :: string s2 (s1.begin (), s1.begin () + 5); // s2 में s1 के पहले 5 अक्षरों को कॉपी करें
टिप्पणियों
std::string
का उपयोग करने से पहले, आपको हेडर string
को शामिल करना चाहिए, क्योंकि इसमें फ़ंक्शन / ऑपरेटर / ओवरलोड शामिल हैं जो अन्य हेडर (उदाहरण के लिए iostream
) शामिल नहीं हैं।
Nullptr के साथ const char * कंस्ट्रक्टर का उपयोग करने से अपरिभाषित व्यवहार होता है।
std::string oops(nullptr);
std::cout << oops << "\n";
यदि कोई index >= size()
तो std::out_of_range
अपवाद at
फेंकता है।
operator[]
का व्यवहार operator[]
थोड़ा और अधिक जटिल है, सभी मामलों में इसका अपरिभाषित व्यवहार है यदि index > size()
, लेकिन जब index == size()
:
- एक नॉन-कास्ट स्ट्रिंग पर, व्यवहार अपरिभाषित है ;
- एक तार स्ट्रिंग पर, मूल्य
CharT()
( शून्य वर्ण) के साथ एक चरित्र का संदर्भ दिया जाता है।
- मान
CharT()
( अशक्त वर्ण) वाले वर्ण का संदर्भ दिया जाता है। - इस संदर्भ को संशोधित करना अपरिभाषित व्यवहार है ।
C ++ 14 के बाद से, "foo"
का उपयोग करने के बजाय, "foo"s
का उपयोग करने की सिफारिश की जाती है, क्योंकि s
एक उपयोगकर्ता-परिभाषित शाब्दिक प्रत्यय है , जो const char*
"foo"
को std::string
"foo"
रूपांतरित करता है। ।
नोट: आपको शाब्दिक s
पाने के लिए नेमस्पेस std::string_literals
या std::literals
std::string_literals
का उपयोग करना होगा।
विभाजन
एक स्ट्रिंग को विभाजित करने के लिए std::string::substr
का प्रयोग करें। इस सदस्य फ़ंक्शन के दो संस्करण हैं।
पहला एक प्रारंभिक स्थिति लेता है जिसमें से रिटर्निंग सबस्ट्रिंग शुरू होना चाहिए। प्रारंभिक स्थिति सीमा (0, str.length()]
में मान्य होनी चाहिए:
std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(11); // "bar and world!"
दूसरा एक प्रारंभिक स्थिति और नए स्थानापन्न की कुल लंबाई लेता है। लंबाई के बावजूद, सबस्ट्रिंग स्रोत स्ट्रिंग के अंत से पहले कभी नहीं जाएगा:
std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(15, 3); // "and"
ध्यान दें कि आप बिना किसी तर्क के भी substr
को कॉल कर सकते हैं, इस स्थिति में स्ट्रिंग की एक सटीक प्रति वापस आ जाती है
std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(); // "Hello foo, bar and world!"
स्ट्रिंग प्रतिस्थापन
स्थिति से बदलें
std::string
एक भाग को बदलने के लिए आप std::string
से replace
विधि का उपयोग कर सकते हैं।
replace
में बहुत सारे उपयोगी अधिभार हैं:
//Define string
std::string str = "Hello foo, bar and world!";
std::string alternate = "Hello foobar";
//1)
str.replace(6, 3, "bar"); //"Hello bar, bar and world!"
//2)
str.replace(str.begin() + 6, str.end(), "nobody!"); //"Hello nobody!"
//3)
str.replace(19, 5, alternate, 6, 6); //"Hello foo, bar and foobar!"
//4)
str.replace(19, 5, alternate, 6); //"Hello foo, bar and foobar!"
//5)
str.replace(str.begin(), str.begin() + 5, str.begin() + 6, str.begin() + 9);
//"foo foo, bar and world!"
//6)
str.replace(0, 5, 3, 'z'); //"zzz foo, bar and world!"
//7)
str.replace(str.begin() + 6, str.begin() + 9, 3, 'x'); //"Hello xxx, bar and world!"
//8)
str.replace(str.begin(), str.begin() + 5, { 'x', 'y', 'z' }); //"xyz foo, bar and world!"
एक स्ट्रिंग की घटनाओं को दूसरे स्ट्रिंग के साथ बदलें
का केवल पहली घटना की जगह replace
साथ with
में str
:
std::string replaceString(std::string str,
const std::string& replace,
const std::string& with){
std::size_t pos = str.find(replace);
if (pos != std::string::npos)
str.replace(pos, replace.length(), with);
return str;
}
के सभी घटना की जगह replace
साथ with
में str
:
std::string replaceStringAll(std::string str,
const std::string& replace,
const std::string& with) {
if(!replace.empty()) {
std::size_t pos = 0;
while ((pos = str.find(replace, pos)) != std::string::npos) {
str.replace(pos, replace.length(), with);
pos += with.length();
}
}
return str;
}
कड़ी
आप ओवरलोडेड +
और +=
ऑपरेटरों का उपयोग करके std::string
एस का उपयोग कर सकते हैं। +
ऑपरेटर का उपयोग करना:
std::string hello = "Hello";
std::string world = "world";
std::string helloworld = hello + world; // "Helloworld"
+=
ऑपरेटर का उपयोग करना:
std::string hello = "Hello";
std::string world = "world";
hello += world; // "Helloworld"
आप स्ट्रिंग स्ट्रिंग सहित सी स्ट्रिंग को भी जोड़ सकते हैं:
std::string hello = "Hello";
std::string world = "world";
const char *comma = ", ";
std::string newhelloworld = hello + comma + world + "!"; // "Hello, world!"
तुम भी उपयोग कर सकते हैं push_back()
पीछे धकेलने के लिए अलग-अलग char
रों:
std::string s = "a, b, ";
s.push_back('c'); // "a, b, c"
इसमें append()
भी है, जो कि बहुत ज्यादा +=
:
std::string app = "test and ";
app.append("test"); // "test and test"
किसी पात्र तक पहुँचना
एक std::string
से वर्णों को निकालने के कई तरीके हैं और प्रत्येक सूक्ष्म रूप से भिन्न है।
std::string str("Hello world!");
ऑपरेटर [] (एन)
अनुक्रमणिका n पर वर्ण का संदर्भ देता है।
std::string::operator[]
सीमा-जाँच नहीं है और एक अपवाद नहीं है। कॉल करने वाले के लिए जिम्मेदार है कि सूचकांक स्ट्रिंग की सीमा के भीतर है:
char c = str[6]; // 'w'
पर (एन)
अनुक्रमणिका n पर वर्ण का संदर्भ देता है।
std::string::at
है सीमा जाँच की, और फेंक देते हैं std::out_of_range
अगर सूचकांक स्ट्रिंग की श्रेणी में नहीं है:
char c = str.at(7); // 'o'
नोट: यदि स्ट्रिंग खाली है, तो इन दोनों उदाहरणों का अपरिभाषित व्यवहार होगा।
सामने ()
पहले चरित्र का संदर्भ देता है:
char c = str.front(); // 'H'
वापस()
अंतिम चरित्र का संदर्भ देता है:
char c = str.back(); // '!'
Tokenize
रन-टाइम में कम से कम महंगी से लेकर सबसे महंगी तक की सूची:
str::strtok
सबसे सस्ती मानक प्रदान की गई टोकन विधि है, यह परिसीमन को टोकन के बीच संशोधित करने की भी अनुमति देता है, लेकिन यह आधुनिक C ++ के साथ 3 कठिनाइयों को जन्म देता है:-
std::strtok
उपयोग एक ही समय में कईstrings
पर नहीं किया जा सकता है (हालांकि कुछ कार्यान्वयन इसका समर्थन करने के लिए बढ़ाते हैं, जैसे:strtok_s
) - एक ही कारण के लिए
std::strtok
उपयोग एक साथ कई थ्रेड्स पर नहीं किया जा सकता है (उदाहरण के लिए इसे लागू किया जा सकता है, उदाहरण के लिए: Visual Studio का कार्यान्वयन थ्रेड सुरक्षित है ) - कॉलिंग
std::strtok
को संशोधित करता हैstd::string
यह जिस पर चल रहा हैstd::string
, इसलिए इसेconst string
s,const char*
s, या शाब्दिक स्ट्रिंग्स पर उपयोग नहीं किया जा सकता है, इनमें से किसी को भीstd::strtok
या पर संचालित करने के लिएstd::string
जिनके कंटेंट को संरक्षित करने की आवश्यकता है, इनपुट को कॉपी करना होगा, फिर कॉपी को ऑपरेट किया जा सकता है
आम तौर पर इनमें से कोई भी विकल्प लागत टोकन की आवंटन लागत में छिपी होगी, लेकिन अगर सबसे सस्ता एल्गोरिथ्म आवश्यक है और
std::strtok
की कठिनाइयां एक हाथ से काता हुआ समाधान पर विचार करने योग्य नहीं हैं ।-
// String to tokenize
std::string str{ "The quick brown fox" };
// Vector to store tokens
vector<std::string> tokens;
for (auto i = strtok(&str[0], " "); i != NULL; i = strtok(NULL, " "))
tokens.push_back(i);
-
std::istream_iterator
धारा के निष्कर्षण ऑपरेटर का उपयोग करता है। यदि इनपुटstd::string
को श्वेत-स्थान सीमांकित किया गया है तो यहstd::strtok
पर विस्तार करने में सक्षम हैstd::strtok
विकल्प अपनी कठिनाइयों को समाप्त करके, इनलाइन tokenization की अनुमति देता है जिससे एकconst vector<string>
की पीढ़ीconst vector<string>
समर्थन करता है, और कई के लिए समर्थन जोड़कर सफेद-अंतरिक्ष वर्ण का परिसीमन:
// String to tokenize
const std::string str("The quick \tbrown \nfox");
std::istringstream is(str);
// Vector to store tokens
const std::vector<std::string> tokens = std::vector<std::string>(
std::istream_iterator<std::string>(is),
std::istream_iterator<std::string>());
-
std::regex_token_iterator
एकstd::regex
का उपयोग करकेstd::regex_token_iterator
उपयोग करता है। यह अधिक लचीली सीमांकक परिभाषा प्रदान करता है। उदाहरण के लिए, गैर-सीमांकित अल्पविराम और श्वेत-स्थान:
// String to tokenize
const std::string str{ "The ,qu\\,ick ,\tbrown, fox" };
const std::regex re{ "\\s*((?:[^\\\\,]|\\\\.)*?)\\s*(?:,|$)" };
// Vector to store tokens
const std::vector<std::string> tokens{
std::sregex_token_iterator(str.begin(), str.end(), re, 1),
std::sregex_token_iterator()
};
अधिक जानकारी के लिए regex_token_iterator
उदाहरण देखें।
(कास्ट) चार में रूपांतरण *
एक std::string
के डेटा में const char*
एक्सेस पाने के लिए आप string के c_str()
मेंबर फंक्शन का उपयोग कर सकते हैं। ध्यान रखें कि सूचक केवल तब तक ही मान्य है जब तक कि std::string
object दायरे में है और अपरिवर्तित रहता है, इसका अर्थ है कि ऑब्जेक्ट पर केवल const
विधियाँ ही कॉल की जा सकती हैं।
data()
सदस्य फ़ंक्शन का उपयोग एक परिवर्तनीय char*
प्राप्त करने के लिए किया जा सकता है, जिसका उपयोग std::string
ऑब्जेक्ट के डेटा में हेरफेर करने के लिए किया जा सकता है।
एक परिवर्तनीय char*
भी पहले चरित्र का पता लेने के द्वारा प्राप्त किया जा सकता है: &s[0]
। C ++ 11 के भीतर, यह एक अच्छी तरह से गठित, शून्य-समाप्त स्ट्रिंग उपज की गारंटी है। ध्यान दें कि &s[0]
अच्छी तरह से गठित है, भले ही s
खाली है, जबकि &s.front()
यदि अपरिभाषित है s
खाली है।
std::string str("This is a string.");
const char* cstr = str.c_str(); // cstr points to: "This is a string.\0"
const char* data = str.data(); // data points to: "This is a string.\0"
std::string str("This is a string.");
// Copy the contents of str to untie lifetime from the std::string object
std::unique_ptr<char []> cstr = std::make_unique<char[]>(str.size() + 1);
// Alternative to the line above (no exception safety):
// char* cstr_unsafe = new char[str.size() + 1];
std::copy(str.data(), str.data() + str.size(), cstr);
cstr[str.size()] = '\0'; // A null-terminator needs to be added
// delete[] cstr_unsafe;
std::cout << cstr.get();
एक स्ट्रिंग में वर्ण (एस) ढूँढना
वर्ण या अन्य स्ट्रिंग खोजने के लिए, आप std::string::find
उपयोग कर सकते std::string::find
। यह पहले मैच के पहले चरित्र की स्थिति देता है। यदि कोई मिलान नहीं मिला, तो फ़ंक्शन std::string::npos
std::string str = "Curiosity killed the cat";
auto it = str.find("cat");
if (it != std::string::npos)
std::cout << "Found at position: " << it << '\n';
else
std::cout << "Not found!\n";
स्थिति पर पाया: 21
खोज कार्यों को निम्नलिखित कार्यों द्वारा और विस्तारित किया जाता है:
find_first_of // Find first occurrence of characters
find_first_not_of // Find first absence of characters
find_last_of // Find last occurrence of characters
find_last_not_of // Find last absence of characters
ये फ़ंक्शन आपको स्ट्रिंग के अंत से वर्णों की खोज करने की अनुमति दे सकते हैं, साथ ही साथ नकारात्मक मामले (जैसे वर्ण स्ट्रिंग में नहीं हैं) को खोजने की अनुमति दे सकते हैं। यहाँ एक उदाहरण है:
std::string str = "dog dog cat cat";
std::cout << "Found at position: " << str.find_last_of("gzx") << '\n';
स्थिति पर पाया: 6
नोट: ध्यान रखें कि उपरोक्त फ़ंक्शन सब्सट्रिंग्स की खोज नहीं करते हैं, बल्कि खोज स्ट्रिंग में निहित वर्णों के लिए हैं। इस स्थिति में, 'g'
की अंतिम स्थिति 6
पर पाई गई (अन्य वर्ण नहीं पाए गए)।
प्रारंभ / अंत में ट्रिमिंग वर्ण
इस उदाहरण के लिए हेडर <algorithm>
, <locale>
, और <utility>
।
अनुक्रम या स्ट्रिंग को ट्रिम करने का अर्थ है एक निश्चित विधेय से मेल खाते सभी प्रमुख और अनुगामी तत्वों (या वर्णों) को हटाना। हम पहले अनुगामी तत्वों को ट्रिम करते हैं, क्योंकि इसमें किसी भी तत्व को स्थानांतरित करना शामिल नहीं है, और फिर प्रमुख तत्वों को ट्रिम करना है। ध्यान दें कि सभी प्रकार के std::basic_string
(जैसे std::string
और std::wstring
) के लिए नीचे दिए गए सामान्यीकरण, और गलती से अनुक्रम कंटेनरों के लिए भी (जैसे std::vector
और std::list
)।
template <typename Sequence, // any basic_string, vector, list etc.
typename Pred> // a predicate on the element (character) type
Sequence& trim(Sequence& seq, Pred pred) {
return trim_start(trim_end(seq, pred), pred);
}
अनुगामी तत्वों को ट्रिम करने में अंतिम तत्व को विधेय से मेल नहीं खाना, और वहाँ से मिटाना शामिल है:
template <typename Sequence, typename Pred>
Sequence& trim_end(Sequence& seq, Pred pred) {
auto last = std::find_if_not(seq.rbegin(),
seq.rend(),
pred);
seq.erase(last.base(), seq.end());
return seq;
}
प्रमुख तत्वों को ट्रिम करने में पहला तत्व ढूंढना शामिल है जो विधेय से मेल नहीं खा रहा है और वहां तक मिटा रहा है:
template <typename Sequence, typename Pred>
Sequence& trim_start(Sequence& seq, Pred pred) {
auto first = std::find_if_not(seq.begin(),
seq.end(),
pred);
seq.erase(seq.begin(), first);
return seq;
}
एक std::string
हम std::isspace()
ट्रिमिंग के लिए उपरोक्त विशेषज्ञ का उपयोग कर सकते हैं: हम एक predicate के रूप में std::isspace()
फ़ंक्शन का उपयोग कर सकते हैं:
std::string& trim(std::string& str, const std::locale& loc = std::locale()) {
return trim(str, [&loc](const char c){ return std::isspace(c, loc); });
}
std::string& trim_start(std::string& str, const std::locale& loc = std::locale()) {
return trim_start(str, [&loc](const char c){ return std::isspace(c, loc); });
}
std::string& trim_end(std::string& str, const std::locale& loc = std::locale()) {
return trim_end(str, [&loc](const char c){ return std::isspace(c, loc); });
}
इसी प्रकार, हम std::iswspace()
फ़ंक्शन for std::wstring
आदि का उपयोग कर सकते हैं।
यदि आप एक नया अनुक्रम बनाना चाहते हैं जो एक छंटनी की गई प्रतिलिपि है, तो आप एक अलग फ़ंक्शन का उपयोग कर सकते हैं:
template <typename Sequence, typename Pred>
Sequence trim_copy(Sequence seq, Pred pred) { // NOTE: passing seq by value
trim(seq, pred);
return seq;
}
तुलनात्मक तुलना
दो std::string
रों कोषगत ऑपरेटर्स का उपयोग तुलना की जा सकती ==
, !=
, <
, <=
, >
, और >=
:
std::string str1 = "Foo";
std::string str2 = "Bar";
assert(!(str1 < str2));
assert(str > str2);
assert(!(str1 <= str2));
assert(str1 >= str2);
assert(!(str1 == str2));
assert(str1 != str2);
ये सभी फ़ंक्शंस अंतर्निहित std::string::compare()
विधि का उपयोग तुलना करने के लिए करते हैं, और सुविधा बूलियन मानों के लिए वापस लौटते हैं। वास्तविक कार्यान्वयन की परवाह किए बिना, इन कार्यों के संचालन की व्याख्या इस प्रकार की जा सकती है:
ऑपरेटर
==
:यदि
str1.length() == str2.length()
और प्रत्येक वर्ण जोड़ी मेल खाती है, तोtrue
, अन्यथाfalse
।ऑपरेटर
!=
:यदि
str1.length() != str2.length()
या एक वर्ण जोड़ी मेल नहीं खाती है, तोtrue
, अन्यथा यहfalse
।ऑपरेटर
<
या ऑपरेटर>
:पहले अलग-अलग चरित्र की जोड़ी पाता है, उनकी तुलना करता है और फिर बूलियन परिणाम देता है।
ऑपरेटर
<=
या ऑपरेटर>=
:पहले अलग-अलग चरित्र की जोड़ी पाता है, उनकी तुलना करता है और फिर बूलियन परिणाम देता है।
नोट: वर्ण वर्ण जोड़ी का अर्थ है समान पदों के दोनों तारों में संबंधित वर्ण। बेहतर समझ के लिए, यदि दो उदाहरण स्ट्रिंग्स str1
और str2
, और उनकी लंबाई क्रमशः n
और m
है, तो दोनों स्ट्रिंग्स के चरित्र जोड़े का अर्थ है प्रत्येक str1[i]
और str2[i]
जोड़े जहां मैं = 0, 1, 2, 2। .., अधिकतम (n, m) । यदि किसी भी i के लिए, जहां संबंधित वर्ण मौजूद नहीं है, अर्थात, जब मैं n
या m
से अधिक या बराबर है, तो इसे सबसे कम मूल्य माना जाएगा।
यहाँ <
का उपयोग करने का एक उदाहरण है:
std::string str1 = "Barr";
std::string str2 = "Bar";
assert(str2 < str1);
चरण इस प्रकार हैं:
- पहले वर्णों की तुलना करें,
'B' == 'B'
- आगे बढ़ते हैं। - दूसरे वर्णों की तुलना करें,
'a' == 'a'
- आगे बढ़ें। - तीसरे वर्णों की तुलना करें,
'r' == 'r'
- आगे बढ़ें। -
str2
रेंज अब समाप्त हो गई है, जबकिstr1
रेंज में अभी भी अक्षर हैं। इस प्रकार,str2 < str1
।
एसटीडी में रूपांतरण :: wstring
C ++ में, वर्णों के अनुक्रमों का प्रतिनिधित्व std::basic_string
वर्ग को एक देशी वर्ण प्रकार के साथ करके किया जाता है। मानक पुस्तकालय द्वारा परिभाषित दो प्रमुख संग्रह हैं std::string
और std::wstring
:
std::string
कोchar
तत्वों के साथ बनाया गया हैstd::wstring
कोwchar_t
तत्वों के साथ बनाया गया है
दो प्रकारों के बीच बदलने के लिए, wstring_convert
उपयोग wstring_convert
:
#include <string>
#include <codecvt>
#include <locale>
std::string input_str = "this is a -string-, which is a sequence based on the -char- type.";
std::wstring input_wstr = L"this is a -wide- string, which is based on the -wchar_t- type.";
// conversion
std::wstring str_turned_to_wstr = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(input_str);
std::string wstr_turned_to_str = std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(input_wstr);
प्रयोज्य और / या पठनीयता में सुधार करने के लिए, आप रूपांतरण करने के लिए कार्यों को परिभाषित कर सकते हैं:
#include <string>
#include <codecvt>
#include <locale>
using convert_t = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_t, wchar_t> strconverter;
std::string to_string(std::wstring wstr)
{
return strconverter.to_bytes(wstr);
}
std::wstring to_wstring(std::string str)
{
return strconverter.from_bytes(str);
}
नमूना उपयोग:
std::wstring a_wide_string = to_wstring("Hello World!");
यह निश्चित रूप से std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("Hello World!")
तुलना में अधिक पठनीय है std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("Hello World!")
।
कृपया ध्यान दें कि char
और wchar_t
नहीं है, और बाइट्स में आकार का कोई संकेत नहीं देता है। उदाहरण के लिए, wchar_t
को आमतौर पर 2-बाइट्स डेटा प्रकार के रूप में लागू किया जाता है और इसमें आमतौर पर विंडोज़ के तहत UTF-16 एन्कोडेड डेटा (या विंडोज 2000 से पहले के संस्करणों में UCS-2) और UTF-32 के तहत 4-बाइट डेटा प्रकार एन्कोडेड के रूप में शामिल होता है लिनक्स। यह नए प्रकार के char16_t
और char32_t
, जिन्हें C ++ 11 में पेश किया गया था और char32_t
किसी भी UTF16 या UTF32 "वर्ण" (या अधिक सटीक, कोड बिंदु ) को धारण करने के लिए पर्याप्त होने की गारंटी है।
Std :: string_view वर्ग का उपयोग करना
सी ++ 17 द्वारा प्रस्तुत std::string_view
, जो केवल की एक गैर मालिक रेंज है const char
रों, या तो संकेत की एक जोड़ी या एक सूचक और लंबाई के रूप में कार्यान्वयन। यह फ़ंक्शन के लिए एक बेहतर पैरामीटर प्रकार है जिसमें गैर-परिवर्तनीय स्ट्रिंग डेटा की आवश्यकता होती है। C ++ 17 से पहले, इसके लिए तीन विकल्प थे:
void foo(std::string const& s); // pre-C++17, single argument, could incur
// allocation if caller's data was not in a string
// (e.g. string literal or vector<char> )
void foo(const char* s, size_t len); // pre-C++17, two arguments, have to pass them
// both everywhere
void foo(const char* s); // pre-C++17, single argument, but need to call
// strlen()
template <class StringT>
void foo(StringT const& s); // pre-C++17, caller can pass arbitrary char data
// provider, but now foo() has to live in a header
इन सभी को प्रतिस्थापित किया जा सकता है:
void foo(std::string_view s); // post-C++17, single argument, tighter coupling
// zero copies regardless of how caller is storing
// the data
ध्यान दें कि std::string_view
अपने अंतर्निहित डेटा को संशोधित नहीं कर सकता है ।
जब आप अनावश्यक प्रतियों से बचना चाहते हैं तो string_view
उपयोगी है।
यह कार्यक्षमता का एक उपयोगी सबसेट प्रदान करता है जो std::string
करता है, हालाँकि कुछ फ़ंक्शन अलग तरह से व्यवहार करते हैं:
std::string str = "lllloooonnnngggg sssstttrrriiinnnggg"; //A really long string
//Bad way - 'string::substr' returns a new string (expensive if the string is long)
std::cout << str.substr(15, 10) << '\n';
//Good way - No copies are created!
std::string_view view = str;
// string_view::substr returns a new string_view
std::cout << view.substr(15, 10) << '\n';
प्रत्येक पात्र के माध्यम से लूपिंग
std::string
पुनरावृत्तियों का समर्थन करती है, और इसलिए आप प्रत्येक वर्ण के माध्यम से पुनरावृत्त करने के लिए एक राउंड आधारित लूप का उपयोग कर सकते हैं:
std::string str = "Hello World!";
for (auto c : str)
std::cout << c;
आप हर पात्र के माध्यम से पाश के for
"पारंपरिक" का उपयोग कर सकते हैं:
std::string str = "Hello World!";
for (std::size_t i = 0; i < str.length(); ++i)
std::cout << str[i];
पूर्णांक / फ्लोटिंग पॉइंट प्रकारों में रूपांतरण
एक std::string
एक संख्या युक्त std::string
को पूर्णांक प्रकार, या एक अस्थायी बिंदु प्रकार में परिवर्तित किया जा सकता है, रूपांतरण कार्यों का उपयोग करके।
ध्यान दें कि ये सभी फ़ंक्शन इनपुट-स्ट्रिंग को पार्स करना बंद कर देते हैं जैसे ही वे एक गैर-संख्यात्मक चरित्र का सामना करते हैं, इसलिए "123abc"
को 123
में बदल दिया जाएगा।
std::ato*
फ़ंक्शंस का परिवार C- स्टाइल स्ट्रिंग्स (कैरेक्टर एरे) को पूर्णांक या फ्लोटिंग-पॉइंट प्रकारों में परिवर्तित करता है:
std::string ten = "10";
double num1 = std::atof(ten.c_str());
int num2 = std::atoi(ten.c_str());
long num3 = std::atol(ten.c_str());
long long num4 = std::atoll(ten.c_str());
हालाँकि, इन कार्यों का उपयोग हतोत्साहित किया जाता है क्योंकि वे स्ट्रिंग को पार्स करने में विफल होने पर 0
वापस कर देते हैं। यह बुरा है क्योंकि 0
भी एक वैध परिणाम हो सकता है, उदाहरण के लिए यदि इनपुट स्ट्रिंग "0" था, तो यह निर्धारित करना असंभव है कि क्या रूपांतरण वास्तव में विफल हो गया है।
नए std::sto*
फ़ंक्शन के परिवार std::string
को पूर्णांक या फ्लोटिंग-पॉइंट प्रकारों में परिवर्तित करते हैं, और अपवादों को फेंक देते हैं यदि वे उनके इनपुट को पार्स नहीं कर सकते। यदि संभव हो तो आपको इन कार्यों का उपयोग करना चाहिए :
std::string ten = "10";
int num1 = std::stoi(ten);
long num2 = std::stol(ten);
long long num3 = std::stoll(ten);
float num4 = std::stof(ten);
double num5 = std::stod(ten);
long double num6 = std::stold(ten);
इसके अलावा, ये कार्य भी std::ato*
परिवार के विपरीत अष्टाधारी और षष्ठ भावों को संभालते हैं। दूसरा पैरामीटर इनपुट स्ट्रिंग में पहले अनकंटेक्टेड कैरेक्टर का पॉइंटर है (यहाँ सचित्र नहीं है), और तीसरा पैरामीटर उपयोग के लिए बेस है। 0
ऑक्टल ( 0
शुरू) और हेक्स ( 0x
या 0X
शुरू) की स्वचालित पहचान है, और किसी भी अन्य मूल्य का उपयोग करने के लिए आधार है
std::string ten = "10";
std::string ten_octal = "12";
std::string ten_hex = "0xA";
int num1 = std::stoi(ten, 0, 2); // Returns 2
int num2 = std::stoi(ten_octal, 0, 8); // Returns 10
long num3 = std::stol(ten_hex, 0, 16); // Returns 10
long num4 = std::stol(ten_hex); // Returns 0
long num5 = std::stol(ten_hex, 0, 0); // Returns 10 as it detects the leading 0x
चरित्र एनकोडिंग के बीच परिवर्तित
एन्कोडिंग के बीच परिवर्तित करना C ++ 11 के साथ आसान है और अधिकांश कंप्रेशर्स इसे <codecvt>
और <locale>
हेडर के माध्यम से क्रॉस-प्लेटफॉर्म तरीके से निपटने में सक्षम हैं।
#include <iostream>
#include <codecvt>
#include <locale>
#include <string>
using namespace std;
int main() {
// converts between wstring and utf8 string
wstring_convert<codecvt_utf8_utf16<wchar_t>> wchar_to_utf8;
// converts between u16string and utf8 string
wstring_convert<codecvt_utf8_utf16<char16_t>, char16_t> utf16_to_utf8;
wstring wstr = L"foobar";
string utf8str = wchar_to_utf8.to_bytes(wstr);
wstring wstr2 = wchar_to_utf8.from_bytes(utf8str);
wcout << wstr << endl;
cout << utf8str << endl;
wcout << wstr2 << endl;
u16string u16str = u"foobar";
string utf8str2 = utf16_to_utf8.to_bytes(u16str);
u16string u16str2 = utf16_to_utf8.from_bytes(utf8str2);
return 0;
}
ध्यान रहे कि विजुअल स्टूडियो 2015 इन रूपांतरण के लिए समर्थन करता है प्रदान करता है, लेकिन एक बग उनके पुस्तकालय कार्यान्वयन में के लिए एक अलग टेम्पलेट का उपयोग करने की आवश्यकता है wstring_convert
जब से निपटने char16_t
:
using utf16_char = unsigned short;
wstring_convert<codecvt_utf8_utf16<utf16_char>, utf16_char> conv_utf8_utf16;
void strings::utf16_to_utf8(const std::u16string& utf16, std::string& utf8)
{
std::basic_string<utf16_char> tmp;
tmp.resize(utf16.length());
std::copy(utf16.begin(), utf16.end(), tmp.begin());
utf8 = conv_utf8_utf16.to_bytes(tmp);
}
void strings::utf8_to_utf16(const std::string& utf8, std::u16string& utf16)
{
std::basic_string<utf16_char> tmp = conv_utf8_utf16.from_bytes(utf8);
utf16.clear();
utf16.resize(tmp.length());
std::copy(tmp.begin(), tmp.end(), utf16.begin());
}
अगर एक स्ट्रिंग दूसरे का उपसर्ग है तो जाँच करना
C ++ 14 में, यह आसानी से std::mismatch
द्वारा किया जाता है जो दो श्रेणियों से पहली बेमेल जोड़ी लौटाता है:
std::string prefix = "foo";
std::string string = "foobar";
bool isPrefix = std::mismatch(prefix.begin(), prefix.end(),
string.begin(), string.end()).first == prefix.end();
ध्यान दें कि mismatch()
एक रेंज-डेढ़ संस्करण C ++ 14 से पहले मौजूद था, लेकिन यह इस मामले में असुरक्षित है कि दूसरा स्ट्रिंग दो में से छोटा है।
हम अभी भी std::mismatch()
के रेंज-एंड-ए-हाफ वर्जन का उपयोग कर सकते हैं, लेकिन हमें पहले यह जांचने की जरूरत है कि पहला स्ट्रिंग दूसरे के जितना बड़ा है:
bool isPrefix = prefix.size() <= string.size() &&
std::mismatch(prefix.begin(), prefix.end(),
string.begin(), string.end()).first == prefix.end();
std::string_view
, हम बिना ओवरहेड आवंटन या प्रतियां बनाने के बारे में चिंता किए बिना प्रत्यक्ष तुलना लिख सकते हैं:
bool isPrefix(std::string_view prefix, std::string_view full)
{
return prefix == full.substr(0, prefix.size());
}
Std :: string में परिवर्तित करना
std::ostringstream
वस्तु एक में डालने से, एक स्ट्रिंग प्रतिनिधित्व करने के लिए किसी भी स्ट्रीम प्रकार परिवर्तित करने के लिए इस्तेमाल किया जा सकता std::ostringstream
(धारा प्रविष्टि ऑपरेटर के साथ वस्तु <<
) और फिर पूरे परिवर्तित std::ostringstream
एक करने के लिए std::string
।
उदाहरण के लिए int
के लिए:
#include <sstream>
int main()
{
int val = 4;
std::ostringstream str;
str << val;
std::string converted = str.str();
return 0;
}
अपना स्वयं का रूपांतरण फ़ंक्शन, सरल लिखना:
template<class T>
std::string toString(const T& x)
{
std::ostringstream ss;
ss << x;
return ss.str();
}
कार्य करता है लेकिन प्रदर्शन महत्वपूर्ण कोड के लिए उपयुक्त नहीं है।
उपयोगकर्ता-परिभाषित वर्ग यदि चाहें तो स्ट्रीम सम्मिलन ऑपरेटर को लागू कर सकते हैं:
std::ostream operator<<( std::ostream& out, const A& a )
{
// write a string representation of a to out
return out;
}
धाराओं के अलावा, C ++ 11 के बाद से आप std::to_string
(और std::to_wstring
) फ़ंक्शन का भी उपयोग कर सकते हैं, जो सभी मूलभूत प्रकारों के लिए अतिभारित है और इसके पैरामीटर का स्ट्रिंग प्रतिनिधित्व लौटाता है।
std::string s = to_string(0x12f3); // after this the string s contains "4851"