C++/C++11中std::string用法汇总
C++/C++11中std::string是個(gè)模板類(lèi),它是一個(gè)標(biāo)準(zhǔn)庫(kù)。使用string類(lèi)型必須首先包含<string>頭文件。作為標(biāo)準(zhǔn)庫(kù)的一部分,string定義在命名空間std中。
std::string是C++中的字符串。字符串對(duì)象是一種特殊類(lèi)型的容器,專(zhuān)門(mén)設(shè)計(jì)來(lái)操作字符序列。
strings are objects that represent sequences of characters.
The standard string class provides support for such objects with an interface similar to that of a standard container of bytes, but adding features specifically designed to operate with strings of single-byte characters.
The string class is an instantiation of the basic_string class template that uses char (i.e.,bytes) as its character type, with its default char_traits and allocator types.
Note that this class handles bytes independently of the encoding used: If used to handle sequences of multi-byte or variable-length characters (such as UTF-8),all members of this class (such as length or size), as well as its iterators,will still operate in terms of bytes (not actual encoded characters).
一個(gè)容器就是一些特定類(lèi)型對(duì)象的集合。順序容器(sequential container)為程序員提供了控制元素存儲(chǔ)和訪(fǎng)問(wèn)順序的能力。這種順序不依賴(lài)于元素的值,而是與元素加入容器時(shí)的位置相對(duì)應(yīng)。
???????? 標(biāo)準(zhǔn)庫(kù)中的順序容器包括:
???????? (1)、vector:可變大小數(shù)組。支持快速隨機(jī)訪(fǎng)問(wèn)。在尾部之外的位置插入或刪除元素可能很慢。
???????? (2)、deque:雙端隊(duì)列。支持快速隨機(jī)訪(fǎng)問(wèn)。在頭尾位置插入/刪除速度很快。
???????? (3)、list:雙向鏈表。只支持雙向順序訪(fǎng)問(wèn)。在list中任何位置進(jìn)行插入/刪除操作速度都很快。
???????? (4)、forward_list:單向鏈表。只支持單向順序訪(fǎng)問(wèn)。在鏈表任何位置進(jìn)行插入/刪除操作速度都很快。
???????? (5)、array:固定大小數(shù)組。支持快速隨機(jī)訪(fǎng)問(wèn)。不能添加或刪除元素。
???????? (6)、string:與vector相似的容器,但專(zhuān)門(mén)用于保存字符。隨機(jī)訪(fǎng)問(wèn)快。在尾部插入/刪除速度快。
???????? 除了固定大小的array外,其它容器都提供高效、靈活的內(nèi)存管理。我們可以添加和刪除元素,擴(kuò)張和收縮容器的大小。容器保存元素的策略對(duì)容器操作的效率有著固定的,有時(shí)是重大的影響。在某些情況下,存儲(chǔ)策略還會(huì)影響特定容器是否支持特定操作。
???????? 例如,string和vector將元素保存在連續(xù)的內(nèi)存空間中。由于元素是連續(xù)存儲(chǔ)的,由元素的下標(biāo)來(lái)計(jì)算其地址是非常快速的。但是,在這兩種容器的中間位置添加或刪除元素就會(huì)非常耗時(shí):在一次插入或刪除操作后,需要移動(dòng)插入/刪除位置之后的所有元素,來(lái)保持連續(xù)存儲(chǔ)。而且,添加一個(gè)元素有時(shí)可能還需要分配額外的存儲(chǔ)空間。在這種情況下,每個(gè)元素都必須移動(dòng)到新的存儲(chǔ)空間中。
???????? list和forward_list兩個(gè)容器的設(shè)計(jì)目的是令容器任何位置的添加和刪除操作都很快速。作為代價(jià),這兩個(gè)容器不支持元素的隨機(jī)訪(fǎng)問(wèn):為了訪(fǎng)問(wèn)一個(gè)元素,我們只能遍歷整個(gè)容器。而且,與vector、deque和array相比,這兩個(gè)容器的額外內(nèi)存開(kāi)銷(xiāo)也很大。
???????? deque是一個(gè)更為復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。與string和vector類(lèi)似,deque支持快速的隨機(jī)訪(fǎng)問(wèn)。與string和vector一樣,在deque的中間位置添加或刪除元素的代價(jià)(可能)很高。但是,在deque的兩端添加或刪除元素都是很快的,與list或forward_list添加刪除元素的速度相當(dāng)。
???????? forward_list和array是新C++標(biāo)準(zhǔn)增加的類(lèi)型。與內(nèi)置數(shù)組相比,array是一個(gè)種更安全、更容易使用的數(shù)組類(lèi)型。與內(nèi)置數(shù)組類(lèi)似,array對(duì)象的大小是固定的。因此,array不支持添加和刪除元素以及改變?nèi)萜鞔笮〉牟僮鳌orward_list的設(shè)計(jì)目標(biāo)是達(dá)到與最好的手寫(xiě)的單向鏈表數(shù)據(jù)結(jié)構(gòu)相當(dāng)?shù)男阅堋R虼?#xff0c;forward_list沒(méi)有size操作,因?yàn)楸4婊蛴?jì)算其大小就會(huì)比手寫(xiě)鏈表多出額外的開(kāi)銷(xiāo)。對(duì)其他容器而言,size保證是一個(gè)快速的常量時(shí)間的操作。
???????? 通常,使用vector是最好的選擇,除法你有很好的理由選擇其他容器。
???????? 以下是一些選擇容器的基本原則:
???????? (1)、除法你有很好的理由選擇其他容器,否則應(yīng)該使用vector;
???????? (2)、如果你的程序有很多小的元素,且空間的額外開(kāi)銷(xiāo)很重要,則不要使用list或forward_list;
???????? (3)、如果程序要求隨機(jī)訪(fǎng)問(wèn)元素,應(yīng)使用vector或deque;
???????? (4)、如果程序要求在容器的中間插入或刪除元素,應(yīng)使用list或forward_list;
(5)、如果程序需要在頭尾位置插入或刪除元素,但不會(huì)在中間位置進(jìn)行插入或刪除操作,則使用deque;
(6)、如果程序只有在讀取輸入時(shí)才需要在容器中間位置插入元素,隨后需要隨機(jī)訪(fǎng)問(wèn)元素,則:首先,確定是否真的需要在容器中間位置添加元素。當(dāng)處理輸入數(shù)據(jù)時(shí),通常可以很容器地向vector追加數(shù)據(jù),然后再調(diào)用標(biāo)準(zhǔn)庫(kù)的sort函數(shù)來(lái)重排容器中的元素,從而避免在中間位置添加元素。如果必須在中間位置插入元素,考慮在輸入階段使用list,一旦輸入完成,將list中的內(nèi)容拷貝到一個(gè)vector中。
如果你不確定應(yīng)該使用哪種容器,那么可以在程序中只使用vector和list公共的操作:使用迭代器,不使用下標(biāo)操作,避免隨機(jī)訪(fǎng)問(wèn)。這樣,在必要時(shí)選擇使用vector或list都很方便。
一般來(lái)說(shuō),每個(gè)容器都定義在一個(gè)頭文件中,文件名與類(lèi)型名相同。即,deque定義在頭文件deque中,list定義在頭文件list中,以此類(lèi)推。容器均定義為模板類(lèi)。
順序容器幾乎可以保存任意類(lèi)型的元素。特別是,我們可以定義一個(gè)容器,其元素的類(lèi)型是另一個(gè)容器。這種容器的定義與任何其他容器類(lèi)型完全一樣:在尖括號(hào)中指定元素類(lèi)型(此種情況下,是另一種容器類(lèi)型)。typedef basic_string<char, char_traits<char>, allocator<char> > string;
typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring;
typedef basic_string<char16_t, char_traits<char16_t>, allocator<char16_t> > u16string;
typedef basic_string<char32_t, char_traits<char32_t>, allocator<char32_t> > u32string;
下面的測(cè)試代碼包含了std::string的所有用法,主要來(lái)自
http://www.cplusplus.com/reference/string/string/?和《C++ Primer(Fifth Edition)》:
#include "string.hpp"
#include <string>
#include <iostream>
#include <cctype>
#include <cstddef> // std::size_t
#include <fstream>/*typedef basic_string<char, char_traits<char>, allocator<char> > string;typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring;typedef basic_string<char16_t, char_traits<char16_t>, allocator<char16_t> > u16string;typedef basic_string<char32_t, char_traits<char32_t>, allocator<char32_t> > u32string;
*/int test_string_init()
{// 如果使用等號(hào)(=)初始化一個(gè)變量,實(shí)際上執(zhí)行的是拷貝初始化,編譯器把等號(hào)右側(cè)的初始化拷貝到新創(chuàng)建的對(duì)象中去。// 與之相反,如果不使用等號(hào),則執(zhí)行的是直接初始化std::string s1; // 默認(rèn)初始化,s1是一個(gè)空串std::string s2(s1); // s2是s1的副本std::string s3 = s1; // 等價(jià)于s3(s1),s3是s1的副本std::string s4("value"); // s4是字面值"value"的副本,除了字面值最后的那個(gè)空字符外,直接初始化std::string s5 = "value"; // 等價(jià)于s5("value"),s5是字面值"value"的副本,拷貝初始化std::string s6(10, 'c'); // 把s6初始化為由連續(xù)10個(gè)字符c組成的串,直接初始化// 對(duì)于用多個(gè)值進(jìn)行初始化的情況,非要用拷貝初始化的方式來(lái)處理也不是不可以,// 不過(guò)需要顯示地創(chuàng)建一個(gè)(臨時(shí))對(duì)象用于拷貝std::string s7 = std::string(10, 'c'); // 拷貝初始化,等價(jià)于: std::string tmp(10, 'c'); std::string s7 = tmp;// string s(s2, pos2) : s是string s2從下標(biāo)pos2開(kāi)始的字符的拷貝,若pos2>s2.size(),構(gòu)造函數(shù)的行為未定義std::string s8(s4, 2);// string s(cp, n) : s是cp指向的數(shù)組中前n個(gè)字符的拷貝,此數(shù)組至少應(yīng)該包含n個(gè)字符char cp[6] {"abcde"};std::string s9(cp, 2);// string s(s2, pos2, len2) : s是string s2從下標(biāo)pos2開(kāi)始len2個(gè)字符的拷貝。若pos2>s2.size(),構(gòu)造函數(shù)的行為未定義.// 不管len2的值是多少,構(gòu)造函數(shù)至多拷貝s2.size()-pos2個(gè)字符std::string s10(s4, 1, 2);return 0;
}int test_string_base()
{int num{ 0 };std::cin >> num;switch (num) {case 0: {// 讀寫(xiě)string對(duì)象std::string s1;std::cin >> s1; // 將string對(duì)象讀入s1,遇到空白停止, string對(duì)象會(huì)自動(dòng)忽然開(kāi)頭的空白(即空格符、換行符、制表符等)// 并從第一個(gè)真正的字符開(kāi)始讀起,直到遇見(jiàn)下一個(gè)空白為止std::cout << s1 << std::endl; // 輸出s1;std::string s2, s3;std::cin >> s2 >> s3; // 多個(gè)輸入或多個(gè)輸出可以連寫(xiě)在一起std::cout << s2 << s3 << std::endl;}break;case 1: {// 讀取未知數(shù)量的string對(duì)象std::string s4;while (std::cin >> s4) { // 反復(fù)讀取,直至到達(dá)文件末尾(ctrl+z)std::cout << s4 << std::endl; // 逐個(gè)輸出單詞,每個(gè)單詞后面緊跟一個(gè)換行}}break;case 2: {// 使用getline讀取一整行,getline只要一遇到換行符就結(jié)束讀取操作并返回結(jié)果std::string s5;while (std::getline(std::cin, s5)) { // 按ctrl+z退出循環(huán)std::cout << s5 << std::endl; // 觸發(fā)getline函數(shù)返回的那個(gè)換行符實(shí)際上被丟棄掉了,// 得到的string對(duì)象中并不包含該換行符}}break;case 3: {// empty:是否為空返回一個(gè)對(duì)應(yīng)的布爾值// 每次讀入一整行,遇到空行直接跳過(guò)std::string s6;while (std::getline(std::cin, s6)) {if (!s6.empty())std::cout << s6 << std::endl;elsestd::cout << "it is empty" << std::endl;}}break;case 4: {// size: 返回string對(duì)象的長(zhǎng)度(即string對(duì)象中字符的個(gè)數(shù))std::string s7;while (std::getline(std::cin, s7)) {auto len = s7.size(); // size函數(shù)返回的是一個(gè)std::string::size_type類(lèi)型的值,// 它是一個(gè)無(wú)符號(hào)類(lèi)型的值,而且能足夠存放下任何string對(duì)象的大小,std::cout << "string size: " << len << std::endl;}}break;case 5: {// 比較string對(duì)象:大小寫(xiě)敏感:==、!=、<、<=、>、>=std::string s1{ "hello" }, s2{ "Hello" }, s3{"Hello world"};if (s1 > s2)std::cout << "s1 > s2" << std::endl;else if (s1 == s2)std::cout << "s1 == s2" << std::endl;else if (s1 < s2)std::cout << "s1 < s2" << std::endl;if (s2 <= s3)std::cout << "s2 <= s3" << std::endl;}break;case 6: {// +: 其內(nèi)容是把左側(cè)的運(yùn)算對(duì)象與右側(cè)的運(yùn)算對(duì)象串接std::string s1{ "hello, " }, s2{ "world" }, s3;s3 = s1 + s2;std::cout << "s3: " << s3 << std::endl;// 當(dāng)把string對(duì)象和字符字面值及字符串字面值混在一條語(yǔ)句中使用時(shí),// 必須確保每個(gè)加法運(yùn)算符(+)的兩側(cè)的對(duì)象至少有一個(gè)是string,// 不能把字面值直接相加// Note: 字符串字面值與string是不同的類(lèi)型std::string s4{ "csdn blog" }, s5{ "http://blog.csdn.net/" }, s6;s6 = s4 + ": " + s5 + "fengbingchun";std::cout << s6 << std::endl;}break;case 7: {// substr: 返回一個(gè)string,它是原始string的一部分或全部的拷貝,// 可以傳遞給substr一個(gè)可選的開(kāi)始位置和計(jì)數(shù)值std::string s{ "hello world" };std::string s2 = s.substr(0, 5); // s2 = hellostd::string s3 = s.substr(6); // s3 = worldstd::string s4 = s.substr(6, 11); // s3 = world//std::string s5 = s.substr(12); // 拋出一個(gè)out_of_range異常fprintf(stderr, "s2: %s; s3: %s; s4: %s\n", s2.c_str(), s3.c_str(), s4.c_str());// insert、erase、assigns.insert(s.size(), 5, '!'); // 在s末尾插入5個(gè)感嘆號(hào)fprintf(stdout, "s: %s\n", s.c_str());s.erase(s.size() - 5, 5); // 從s刪除最后5個(gè)字符fprintf(stdout, "s: %s\n", s.c_str());const char* cp = "Stately, plump Buck";s.assign(cp, 7); // s = "Stately"fprintf(stdout, "s: %s\n", s.c_str());s.insert(s.size(), cp + 7); // s = "Stately, plump Buck"fprintf(stdout, "s: %s\n", s.c_str());std::string s5{ " some string " }, s6{ " some other string " };s5.insert(0, s6); // 在s5中位置0之前插入s6的拷貝fprintf(stdout, "s5: %s\n", s5.c_str());s5.insert(0, s6, 0, s6.size()); // 在s5[0]之前插入s6中s6[0]開(kāi)始的s6.size()個(gè)字符fprintf(stdout, "s5: %s\n", s5.c_str());// append: 是在末尾進(jìn)行插入操作的一種簡(jiǎn)寫(xiě)形式std::string s7{ "C++ Primer" }, s8{ s7 };s7.insert(s7.size(), " 5th Ed.");s8.append(" 5th Ed.");fprintf(stdout, "s7: %s; s8: %s\n", s7.c_str(), s8.c_str());// replace: 是調(diào)用erase和insert的一種簡(jiǎn)寫(xiě)形式s7.replace(11, 3, "Fifth"); // s7.erase(11, 3); s7.insert(11, "Fifth");fprintf(stdout, "s7: %s\n", s7.c_str());/*s.find(args):查找s中args第一次出現(xiàn)的位置s.rfind(args):查找s中args最后一次出現(xiàn)的位置s.find_first_of(args):在s中查找args中任何一個(gè)字符第一次出現(xiàn)的位置s.find_last_of(args):在s中查找args中任何一個(gè)字符最后一次出現(xiàn)的位置s.find_first_not_of(args):在s中查找第一個(gè)不在args中的字符s.find_last_not_of(args):在s中查找最后一個(gè)不在args中的字符*/// find: 返回第一個(gè)匹配位置的下標(biāo)std::string s9{ "AnnaBelle" };auto pos1 = s9.find("Belle");auto pos2 = s9.find("xxx");fprintf(stdout, "pos1: %d, pos2: %d\n", pos1, pos2); // 4, -1// find_first_of: 查找與給定字符串中任何一個(gè)字符匹配的位置std::string numbers{ "0123456789" }, name{ "r2d2" };auto pos3 = name.find_first_of(numbers);fprintf(stdout, "pos3: %d\n", pos3); // 1, name中第一個(gè)數(shù)字的下標(biāo)// find_first_not_of: 第一個(gè)不在參數(shù)中的字符std::string s10{ "03714p3" };auto pos4 = s10.find_first_not_of(numbers);fprintf(stdout, "pos4: %d\n", pos4); // 5// compare: 返回0(等于)、正數(shù)(大于)或負(fù)數(shù)(小于)auto ret = numbers.compare(name);fprintf(stdout, "compare result: %d\n", ret);// -1// 數(shù)值數(shù)據(jù)與string之間的轉(zhuǎn)換int i{ 43 };std::string s11 = std::to_string(i); // 將整數(shù)i轉(zhuǎn)換為字符表示形式double d = std::stod(s11); // 將字符串s11轉(zhuǎn)換為浮點(diǎn)數(shù)fprintf(stdout, "s11: %s, d: %f\n", s11.c_str(), d);/*to_string(val):一組重載函數(shù),返回?cái)?shù)值val的string表示。val可以是任何算術(shù)類(lèi)型stoi(s,p,b)/stol(s,p,b)/stoul(s,p,b)/stoll(s,p,b)/stoull(s,p,b):返回s的起始子串(表示整數(shù)內(nèi)容)的數(shù)值,返回類(lèi)型分別是int、long、unsigned long、long long、unsigned long long。b表示轉(zhuǎn)換所用的基數(shù),默認(rèn)值為10.p是size_t指針,用來(lái)保存s中第一個(gè)非數(shù)值字符的下標(biāo),p默認(rèn)是0,即,函數(shù)不保存下標(biāo)。stof(s,p)/stod(s,p)/stold(s,p):返回s的起始子串(表示浮點(diǎn)數(shù)內(nèi)容)的數(shù)值,返回值類(lèi)型分別是float、double或long double.參數(shù)p的作用與整數(shù)轉(zhuǎn)換函數(shù)中一樣。*/}break;default:break;}return 0;
}int test_string_cctype()
{/* include <cctype>isalnum(c):當(dāng)c是字母或數(shù)字時(shí)為真isalpha(c):當(dāng)c是字母時(shí)為真isblank(c):當(dāng)c是空白字符時(shí)為真(C++11)iscntrl(c):當(dāng)c時(shí)控制字符時(shí)為真isdigit(c):當(dāng)c是數(shù)字時(shí)為真isgraph(c):當(dāng)c不是空格但可打印時(shí)為真islower(c):當(dāng)c是小寫(xiě)字母時(shí)為真isprint(c):當(dāng)c是可打印字符時(shí)為真(即c是空格或c具有可視形式)ispunct(c):當(dāng)c是標(biāo)點(diǎn)符號(hào)時(shí)為真(即c不是控制字符、數(shù)字、字母、可打印空白中的一種)isspace(c):當(dāng)c是空白時(shí)為真(即c是空格、橫向制表符、縱向制表符、回車(chē)符、換行符、進(jìn)紙符中的一種)isupper(c):當(dāng)c是大寫(xiě)字母時(shí)為真isxdigit(c):當(dāng)c是十六進(jìn)制數(shù)字時(shí)為真tolower(c):如果c是大寫(xiě)字母,輸出對(duì)應(yīng)的小寫(xiě)字母;否則原樣輸出ctoupper(c):如果c是小寫(xiě)字母,輸出對(duì)應(yīng)的大寫(xiě)字母;否則原樣輸出c*/std::string s1{ "Hello World!!!" };decltype(s1.size()) punct_cnt{ 0 };for (auto c : s1) {if (ispunct(c))++punct_cnt;}std::cout << punct_cnt << " punctutation characters in " << s1 << std::endl;for (auto &c : s1) { // 對(duì)于s1中的每個(gè)字符(Note:c是引用)c = toupper(c); // c是一個(gè)引用,因此賦值語(yǔ)句將改變s中字符的值}std::cout << "toupper s1: " << s1 << std::endl;// string對(duì)象的下標(biāo)必須大于等于0而小于s.size()// Note:C++標(biāo)準(zhǔn)并不要求標(biāo)準(zhǔn)庫(kù)檢測(cè)下標(biāo)是否合法。一旦使用了一個(gè)超出范圍的下標(biāo),就會(huì)產(chǎn)生不可預(yù)知的結(jié)果std::string s2{"some string"};for (decltype(s2.size()) index = 0; index != s2.size() && !isspace(s2[index]); ++index) {s2[index] = toupper(s2[index]);}std::cout << "s2: " << s2 << std::endl;// 使用下標(biāo)執(zhí)行隨機(jī)訪(fǎng)問(wèn)const std::string s3{"0123456789ABCDEF"};std::cout << "Enter a series of numbers between 0 and 15"<< "separated by spaces. Hit ENTER when finished: " << std::endl;std::string result;std::string::size_type n;while (std::cin >> n) {if (n < s3.size())result += s3[n];std::cout << "Your hex number is: " << result << std::endl;}return 0;
}static void SplitFilename(const std::string& str)
{std::cout << "Splitting: " << str << '\n';std::size_t found = str.find_last_of("/\\");std::cout << " path: " << str.substr(0, found) << '\n';std::cout << " file: " << str.substr(found + 1) << '\n';
}int test_string_func()
{// reference: http://www.cplusplus.com/reference/string/string/{ // appendstd::string str;std::string str2 = "Writing ";std::string str3 = "print 10 and then 5 more";// used in the same order as described above:str.append(str2); // "Writing "str.append(str3, 6, 3); // "10 "str.append("dots are cool", 5); // "dots "str.append("here: "); // "here: "str.append(10u, '.'); // ".........."str.append(str3.begin() + 8, str3.end()); // " and then 5 more"str.append(5, 0x2E); // "....."std::cout << str << '\n';}{ // assignstd::string str;std::string base = "The quick brown fox jumps over a lazy dog.";// used in the same order as described above:str.assign(base);std::cout << str << '\n';str.assign(base, 10, 9);std::cout << str << '\n'; // "brown fox"str.assign("pangrams are cool", 7);std::cout << str << '\n'; // "pangram"str.assign("c-string");std::cout << str << '\n'; // "c-string"str.assign(10, '*');std::cout << str << '\n'; // "**********"str.assign(10, 0x2D);std::cout << str << '\n'; // "----------"str.assign(base.begin() + 16, base.end() - 12);std::cout << str << '\n'; // "fox jumps over"
}{ // atstd::string str("Test string");for (unsigned i = 0; i<str.length(); ++i) {std::cout << str.at(i);}std::cout << '\n';}{ // back(c++11)std::string str("hello world.");str.back() = '!';std::cout << str << '\n';}{ // begin/endstd::string str("Test string");for (std::string::iterator it = str.begin(); it != str.end(); ++it)std::cout << *it;std::cout << '\n';}{ // capacitystd::string str("Test string");std::cout << "size: " << str.size() << "\n";std::cout << "length: " << str.length() << "\n";std::cout << "capacity: " << str.capacity() << "\n";std::cout << "max_size: " << str.max_size() << "\n";}{ // cbegin/cend(c++11)std::string str("Lorem ipsum");for (auto it = str.cbegin(); it != str.cend(); ++it)std::cout << *it;std::cout << '\n';}{ // clearchar c;std::string str;std::cout << "Please type some lines of text. Enter a dot (.) to finish:\n";do {c = std::cin.get();str += c;if (c == '\n') {std::cout << str;str.clear();}} while (c != '.');}{ // comparestd::string str1("green apple");std::string str2("red apple");if (str1.compare(str2) != 0)std::cout << str1 << " is not " << str2 << '\n';if (str1.compare(6, 5, "apple") == 0)std::cout << "still, " << str1 << " is an apple\n";if (str2.compare(str2.size() - 5, 5, "apple") == 0)std::cout << "and " << str2 << " is also an apple\n";if (str1.compare(6, 5, str2, 4, 5) == 0)std::cout << "therefore, both are apples\n";}{ // copychar buffer[20];std::string str("Test string...");std::size_t length = str.copy(buffer, 6, 5);buffer[length] = '\0';std::cout << "buffer contains: " << buffer << '\n';}{ // crbegin/crend(c++11)std::string str("lorem ipsum");for (auto rit = str.crbegin(); rit != str.crend(); ++rit)std::cout << *rit;std::cout << '\n';}{ // c_strstd::string str("Please split this sentence into tokens");char * cstr = new char[str.length() + 1];std::strcpy(cstr, str.c_str());// cstr now contains a c-string copy of strchar * p = std::strtok(cstr, " ");while (p != 0) {std::cout << p << '\n';p = std::strtok(NULL, " ");}delete[] cstr;}{ // dataint length;std::string str = "Test string";char* cstr = "Test string";if (str.length() == std::strlen(cstr)) {std::cout << "str and cstr have the same length.\n";if (memcmp(cstr, str.data(), str.length()) == 0)std::cout << "str and cstr have the same content.\n";}}{ // emptystd::string content;std::string line;std::cout << "Please introduce a text. Enter an empty line to finish:\n";do {getline(std::cin, line);content += line + '\n';} while (!line.empty());std::cout << "The text you introduced was:\n" << content;}{ // erasestd::string str("This is an example sentence.");std::cout << str << '\n';// "This is an example sentence."str.erase(10, 8); // ^^^^^^^^std::cout << str << '\n';// "This is an sentence."str.erase(str.begin() + 9); // ^std::cout << str << '\n';// "This is a sentence."str.erase(str.begin() + 5, str.end() - 9); // ^^^^^std::cout << str << '\n';// "This sentence."}{ // findstd::string str("There are two needles in this haystack with needles.");std::string str2("needle");// different member versions of find in the same order as above:std::size_t found = str.find(str2);if (found != std::string::npos)std::cout << "first 'needle' found at: " << found << '\n';found = str.find("needles are small", found + 1, 6);if (found != std::string::npos)std::cout << "second 'needle' found at: " << found << '\n';found = str.find("haystack");if (found != std::string::npos)std::cout << "'haystack' also found at: " << found << '\n';found = str.find('.');if (found != std::string::npos)std::cout << "Period found at: " << found << '\n';// let's replace the first needle:str.replace(str.find(str2), str2.length(), "preposition");std::cout << str << '\n';}{ // find_first_not_ofstd::string str("look for non-alphabetic characters...");std::size_t found = str.find_first_not_of("abcdefghijklmnopqrstuvwxyz ");if (found != std::string::npos) {std::cout << "The first non-alphabetic character is " << str[found];std::cout << " at position " << found << '\n';}}{ // find_first_ofstd::string str("Please, replace the vowels in this sentence by asterisks.");std::size_t found = str.find_first_of("aeiou");while (found != std::string::npos) {str[found] = '*';found = str.find_first_of("aeiou", found + 1);}std::cout << str << '\n';}{ // find_last_not_ofstd::string str("Please, erase trailing white-spaces \n");std::string whitespaces(" \t\f\v\n\r");std::size_t found = str.find_last_not_of(whitespaces);if (found != std::string::npos)str.erase(found + 1);elsestr.clear(); // str is all whitespacestd::cout << '[' << str << "]\n";}{ // find_last_ofstd::string str1("/usr/bin/man");std::string str2("c:\\windows\\winhelp.exe");SplitFilename(str1);SplitFilename(str2);}{ // front(c++11)std::string str("test string");str.front() = 'T';std::cout << str << '\n';}{ // get_allocator// reference: http://www.tenouk.com/cpluscodesnippet/cplusbasic_stringget_allocator.html// using the default allocatorstd::string str1 = "1234";std::basic_string <char> str2 = "567ABC";std::basic_string <char, std::char_traits<char>, std::allocator<char> > str3 = "DefauLt";std::cout << "str1 = " << str1 << std::endl;std::cout << "str2 = " << str2 << std::endl;std::cout << "str3 = " << str3 << std::endl;// str4 will use the same allocator class as str1std::basic_string <char> str4(str1.get_allocator());std::basic_string <char>::allocator_type xchar = str1.get_allocator();str4 = "Just a string";std::cout << "str4 = " << str4 << std::endl;if (xchar == str1.get_allocator())std::cout << "The allocator objects xchar and str1.get_allocator() are equal." << std::endl;elsestd::cout << "The allocator objects xchar and str1.get_allocator() are not equal." << std::endl;// you can now call functions on the allocator class xchar used by str1std::string str5(xchar);}{ // insertstd::string str = "to be question";std::string str2 = "the ";std::string str3 = "or not to be";std::string::iterator it;// used in the same order as described above:str.insert(6, str2); // to be (the )questionstr.insert(6, str3, 3, 4); // to be (not )the questionstr.insert(10, "that is cool", 8); // to be not (that is )the questionstr.insert(10, "to be "); // to be not (to be )that is the questionstr.insert(15, 1, ':'); // to be not to be(:) that is the questionit = str.insert(str.begin() + 5, ','); // to be(,) not to be: that is the questionstr.insert(str.end(), 3, '.'); // to be, not to be: that is the question(...)str.insert(it + 2, str3.begin(), str3.begin() + 3); // (or )std::cout << str << '\n';}{ // lengthstd::string str("Test string");std::cout << "The size of str is " << str.length() << " bytes.\n";}{ // max_sizestd::string str("Test string");std::cout << "size: " << str.size() << "\n";std::cout << "length: " << str.length() << "\n";std::cout << "capacity: " << str.capacity() << "\n";std::cout << "max_size: " << str.max_size() << "\n";}{ // operator +=std::string name("John");std::string family("Smith");name += " K. "; // c-stringname += family; // stringname += '\n'; // characterstd::cout << name;}{ // operator =std::string str1, str2, str3;str1 = "Test string: "; // c-stringstr2 = 'x'; // single characterstr3 = str1 + str2; // stringstd::cout << str3 << '\n';}{ // operator []std::string str("Test string");for (int i = 0; i<str.length(); ++i) {std::cout << str[i];}}{ // pop_back(c++11)std::string str("hello world!");str.pop_back();std::cout << str << '\n';}{ // push_backstd::string str;std::ifstream file("test.txt", std::ios::in);if (file) {while (!file.eof()) str.push_back(file.get());}std::cout << str << '\n';}{ // rbegin/rendstd::string str("now step live...");for (std::string::reverse_iterator rit = str.rbegin(); rit != str.rend(); ++rit)std::cout << *rit;}{ // replacestd::string base = "this is a test string.";std::string str2 = "n example";std::string str3 = "sample phrase";std::string str4 = "useful.";// replace signatures used in the same order as described above:// Using positions: 0123456789*123456789*12345std::string str = base; // "this is a test string."str.replace(9, 5, str2); // "this is an example string." (1)str.replace(19, 6, str3, 7, 6); // "this is an example phrase." (2)str.replace(8, 10, "just a"); // "this is just a phrase." (3)str.replace(8, 6, "a shorty", 7); // "this is a short phrase." (4)str.replace(22, 1, 3, '!'); // "this is a short phrase!!!" (5)// Using iterators: 0123456789*123456789*str.replace(str.begin(), str.end() - 3, str3); // "sample phrase!!!" (1)str.replace(str.begin(), str.begin() + 6, "replace"); // "replace phrase!!!" (3)str.replace(str.begin() + 8, str.begin() + 14, "is coolness", 7); // "replace is cool!!!" (4)str.replace(str.begin() + 12, str.end() - 4, 4, 'o'); // "replace is cooool!!!" (5)str.replace(str.begin() + 11, str.end(), str4.begin(), str4.end());// "replace is useful." (6)std::cout << str << '\n';}{ // reservestd::string str;std::ifstream file("test.txt", std::ios::in | std::ios::ate);if (file) {std::ifstream::streampos filesize = file.tellg();str.reserve(filesize);file.seekg(0);while (!file.eof()) {str += file.get();}std::cout << str;}}{ // resizestd::string str("I like to code in C");std::cout << str << '\n';unsigned sz = str.size();str.resize(sz + 2, '+');std::cout << str << '\n';str.resize(14);std::cout << str << '\n';}{ // rfindstd::string str("The sixth sick sheik's sixth sheep's sick.");std::string key("sixth");std::size_t found = str.rfind(key);if (found != std::string::npos)str.replace(found, key.length(), "seventh");std::cout << str << '\n';}{ // shrink_to_fit(c++11)std::string str(100, 'x');std::cout << "1. capacity of str: " << str.capacity() << '\n';str.resize(10);std::cout << "2. capacity of str: " << str.capacity() << '\n';str.shrink_to_fit();std::cout << "3. capacity of str: " << str.capacity() << '\n';}{ // sizestd::string str("Test string");std::cout << "The size of str is " << str.size() << " bytes.\n";}{ // substrstd::string str = "We think in generalities, but we live in details.";// (quoting Alfred N. Whitehead)std::string str2 = str.substr(3, 5); // "think"std::size_t pos = str.find("live"); // position of "live" in strstd::string str3 = str.substr(pos); // get from "live" to the endstd::cout << str2 << ' ' << str3 << '\n';}{ // swapstd::string buyer("money");std::string seller("goods");std::cout << "Before the swap, buyer has " << buyer;std::cout << " and seller has " << seller << '\n';seller.swap(buyer);std::cout << " After the swap, buyer has " << buyer;std::cout << " and seller has " << seller << '\n';}{ // npos/*std::string::npos : public static member constantstatic const size_t npos = -1;npos is a static member constant value with the greatest possible value for an element of type size_t.This constant is defined with a value of -1, which because size_t is an unsigned integral type,it is the largest possible representable value for this type.*/}{ // getlinestd::string name;std::cout << "Please, enter your full name: ";std::getline(std::cin, name);std::cout << "Hello, " << name << "!\n";}{ // operator +std::string firstlevel("com");std::string secondlevel("cplusplus");std::string scheme("http://");std::string hostname;std::string url;hostname = "www." + secondlevel + '.' + firstlevel;url = scheme + hostname;std::cout << url << '\n';}{ // operator <<std::string str = "Hello world!";std::cout << str << '\n';}{ // operator >>std::string name;std::cout << "Please, enter your name: ";std::cin >> name;std::cout << "Hello, " << name << "!\n";}{ // string comparisonsstd::string foo = "alpha";std::string bar = "beta";if (foo == bar) std::cout << "foo and bar are equal\n";if (foo != bar) std::cout << "foo and bar are not equal\n";if (foo< bar) std::cout << "foo is less than bar\n";if (foo> bar) std::cout << "foo is greater than bar\n";if (foo <= bar) std::cout << "foo is less than or equal to bar\n";if (foo >= bar) std::cout << "foo is greater than or equal to bar\n";}{ // swap stringsstd::string buyer("money");std::string seller("goods");std::cout << "Before the swap, buyer has " << buyer;std::cout << " and seller has " << seller << '\n';swap(buyer, seller);std::cout << " After the swap, buyer has " << buyer;std::cout << " and seller has " << seller << '\n';}{ // stod(c++11)std::string orbits("365.24 29.53");std::string::size_type sz; // alias of size_tdouble earth = std::stod(orbits, &sz);double moon = std::stod(orbits.substr(sz));std::cout << "The moon completes " << (earth / moon) << " orbits per Earth year.\n";}{ // stof(c++11)std::string orbits("686.97 365.24");std::string::size_type sz; // alias of size_tfloat mars = std::stof(orbits, &sz);float earth = std::stof(orbits.substr(sz));std::cout << "One martian year takes " << (mars / earth) << " Earth years.\n";}{ // stoi(c++11)std::string str_dec = "2001, A Space Odyssey";std::string str_hex = "40c3";std::string str_bin = "-10010110001";std::string str_auto = "0x7f";std::string::size_type sz; // alias of size_tint i_dec = std::stoi(str_dec, &sz);int i_hex = std::stoi(str_hex, nullptr, 16);int i_bin = std::stoi(str_bin, nullptr, 2);int i_auto = std::stoi(str_auto, nullptr, 0);std::cout << str_dec << ": " << i_dec << " and [" << str_dec.substr(sz) << "]\n";std::cout << str_hex << ": " << i_hex << '\n';std::cout << str_bin << ": " << i_bin << '\n';std::cout << str_auto << ": " << i_auto << '\n';}{ // stol(c++11)std::string str_dec = "1987520";std::string str_hex = "2f04e009";std::string str_bin = "-11101001100100111010";std::string str_auto = "0x7fffff";std::string::size_type sz; // alias of size_tlong li_dec = std::stol(str_dec, &sz);long li_hex = std::stol(str_hex, nullptr, 16);long li_bin = std::stol(str_bin, nullptr, 2);long li_auto = std::stol(str_auto, nullptr, 0);std::cout << str_dec << ": " << li_dec << '\n';std::cout << str_hex << ": " << li_hex << '\n';std::cout << str_bin << ": " << li_bin << '\n';std::cout << str_auto << ": " << li_auto << '\n';}{ // stold(c++11)std::string orbits("90613.305 365.24");std::string::size_type sz; // alias of size_tlong double pluto = std::stod(orbits, &sz);long double earth = std::stod(orbits.substr(sz));std::cout << "Pluto takes " << (pluto / earth) << " years to complete an orbit.\n";}{ // stoll(c++11)std::string str = "8246821 0xffff 020";std::string::size_type sz = 0; // alias of size_twhile (!str.empty()) {long long ll = std::stoll(str, &sz, 0);std::cout << str.substr(0, sz) << " interpreted as " << ll << '\n';str = str.substr(sz);}}{ // stoul(c++11)std::string str{ "1111" };//std::cout << "Enter an unsigned number: ";//std::getline(std::cin, str);unsigned long ul = std::stoul(str, nullptr, 0);std::cout << "You entered: " << ul << '\n';}{ // stoull(c++11)std::string str = "8246821 0xffff 020 -1";std::string::size_type sz = 0; // alias of size_twhile (!str.empty()) {unsigned long long ull = std::stoull(str, &sz, 0);std::cout << str.substr(0, sz) << " interpreted as " << ull << '\n';str = str.substr(sz);}}{ // to_string(c++11)/*string to_string (int val);string to_string (long val);string to_string (long long val);string to_string (unsigned val);string to_string (unsigned long val);string to_string (unsigned long long val);string to_string (float val);string to_string (double val);string to_string (long double val);*/std::string pi = "pi is " + std::to_string(3.1415926);std::string perfect = std::to_string(1 + 2 + 4 + 7 + 14) + " is a perfect number";std::cout << pi << '\n';std::cout << perfect << '\n';}{ // to_wstring(c++11)/*wstring to_wstring (int val);wstring to_wstring (long val);wstring to_wstring (long long val);wstring to_wstring (unsigned val);wstring to_wstring (unsigned long val);wstring to_wstring (unsigned long long val);wstring to_wstring (float val);wstring to_wstring (double val);wstring to_wstring (long double val);*/std::wstring pi = L"pi is " + std::to_wstring(3.1415926);std::wstring perfect = std::to_wstring(1 + 2 + 4 + 7 + 14) + L" is a perfect number";std::wcout << pi << L'\n';std::wcout << perfect << L'\n';}return 0;
}int test_string_ifstream_to_string()
{// reference: http://stackoverflow.com/questions/2602013/read-whole-ascii-file-into-c-stdstringstd::ifstream file("E:/GitCode/Messy_Test/testdata/regex.txt");if (!file) {fprintf(stderr, "read file failed!\n");return -1;}std::string str((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());fprintf(stderr, "file content: \n%s\n", str.c_str());return 0;
}
GitHub: https://github.com/fengbingchun/Messy_Test
總結(jié)
以上是生活随笔為你收集整理的C++/C++11中std::string用法汇总的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Ubuntu14.04 LTS中升级gc
- 下一篇: Caffe源码中Net文件分析