string 的簡單使用及操作
阿新 • • 發佈:2018-12-27
string 類的常見物件的構造
string(); // 構造空的 string 類物件
string(const char* s); // 使用 c 風格的的字串來構造 string 類物件
string(size_t n, char c); // string 類物件中包含 n 個字元 c
string(const string& s); // 拷貝建構函式
string(const string& s, size_t n); // 用 s 中的前 n 個字元構造 string 類的物件
測試程式碼
void TestString1() { cout << "string 類的常見物件的構造" << endl; string s1; // 構造空的 string 類物件 s1 string s2("hello world!!!"); // 使用 c 格式構造 string 類的物件 s2 string s3(10, 'h'); // 用 10 給字元 h 構造 string 類物件 s3 string s4(s2); // 用 s2 構造 string 類物件 s4 string s5(s3, 5); // 用字串 s3 的前五個字元構造 string 類物件 s5 }
string 類的物件的容量操作
size_t size() const 返回字串的有效字元長度 size_t length() const 返回字串的有效字元長度 size_t capacity() const 返回容量,總空間大小 bool empty() const 檢測字串是否為空串 void clear() 清空有效字元 void resize(size_t n, char c) 將有效字元個數改為 n 個,多出的空間用字元 c 填充 void resize(size_t n) 將有效字元個數改為 n 個,多出的空間用 0 填充 void reserve(size_t res_arg = 0) 為字串預留空間
測試程式碼
void TestString2() { cout << "string 類的物件的容量操作" << endl; // string 類物件直接支援 cin 和 cout 輸入與輸出 string s("hello world!!!"); cout << "length:" << s.length() << endl; cout << "size:" << s.size() << endl; cout << "capacity:" << s.capacity() << endl; cout << "s:" << s << endl; // 將 s 中的字串清空,注意:清空時只是將 size 清 0,不改變底層空間大小 s.clear(); cout << "size:" << s.size() << endl; cout << "length:" << s.length() << endl; cout << "capacity:" << s.capacity() << endl; cout << "s:" << s << endl; //將 s 中有效字元個數增加到 10 個,多出位置用字元 a 進行填充 s.resize(10, 'a'); cout << "size:" << s.size() << endl; cout << "length:" << s.length() << endl; cout << "capacity:" << s.capacity() << endl; cout << "s:" << s << endl; //將 s 中有效字元個數增加至 15 個,多出位置用 '\0' 進行填充 //"aaaaaaaaaa\0\0\0\0\0\0\0\0\0\0" s.resize(15); cout << "size:" << s.size() << endl; cout << "length:" << s.length() << endl; cout << "capacity:" << s.capacity() << endl; cout << "s:" << s << endl; //將 s 中有效字元減少至 5 個 s.resize(5); cout << "size:" << s.size() << endl; cout << "length:" << s.length() << endl; cout << "capacity:" << s.capacity() << endl; cout << "s:" << s << endl; }
注意
1、size() 和 length() 方法底層實現原理完全相同,引入 size() 的原因是為了與其他容器的介面保持一致,一般情況下基本都用 size()
2、clear() 只是將 string 中的有效字元清空,不改變底層空間大小
3、resize(size_t n) 與 resize(size_t n, char c) 都是將字串中有效字元個數改變成 n 個,
不同的是當字元個數增多時,resize(n) 用 0 來填充剩餘空間,而 resize(size_t n, char c) 則用字元填充
注意:resize() 在改變元素個數時,如果將元素個數增多,可能會改變底層容量大小 capacity ,
如果是減少有效元素個數,則底層空間大小不變
4、reserve(size_t res_arg = 0) 為 string 預留空間,不改變有效元素個數,
當 reserve 的引數小於 string 的底層空間時,reserve 不會改變容量大小
測試程式碼
void TestString3()
{
cout << "測試 reserve 是否會改變 string 中有效元素個數" << endl;
//測試 reserve 是否會改變 string 中有效元素個數
string s;
s.reserve(100);
cout << "size:" << s.size() << endl;
cout << "capacity:" << s.capacity() << endl;
//測試 reserve 引數小於 string 底層空間大小時,是否會將空間縮小
s.reserve(50);
cout << "size:" << s.size() << endl;
cout << "capacity:" << s.capacity() << endl;
}
string 類物件的訪問操作
char& operator[](size_t pos) 返回位置 pos 的字元,const string 類物件呼叫
const char& operator[](size_t pos) //返回 pos 位置的字元,非 const string 類物件呼叫
void TestString4()
{
string s1("hello world!!!");
const string s2("hello world!!!");
cout << s1 << " " << s2 << endl;
cout << s1[0] << " " << s2[0] << endl;
s1[0] = 'H';
cout << "s1:" << s1 << endl;
for (size_t i = 0; i < s1.size(); ++i)
{
cout << "s1:" << s1[i];
}
cout << endl;
//s2[0] = 'H' 不能通過編譯 , const 型別物件不可以修改
}
string 類物件的修改操作
void push_bask(char c); 在字串尾插入字元 c
string& append(const char* s); 在字串後面追加一個字串
string& operator+=(const string& str); 在字串後面追加字串
string& operator+=(const char* c); 在字串後面追加 c 風格字串
string& operator+=(const char c) 在字串後面追加字元 c
const char* c_str() const 返回 c 風格的字串
size_t find(char c, size_t pos = 0) const 從字串 pos 位置往後開始找字元 c ,返回該字元所在字串的位置
size_t rfind(char* c, size_t pos = npos) const 從字串 pos 位置開始向前找字元 c ,返回該字元所在位置
string substr(size_t pos = 0, size_t n = npos) const 在 str 中從 pos 位置開始擷取 n 個字元,然後將其返回
void TestString5()
{
string str;
str.push_back(' '); // 在str後插入空格
str.append("hello"); // 在str後追加一個字元"hello"
str += 'b'; // 在str後追加一個字元'b'
str += "it"; // 在str後追加一個字串"it"
cout<<str<<endl;
cout<<str.c_str()<<endl; // 以C語言的方式列印字串
// 獲取file的字尾
string file("string.cpp");
size_t pos = file.rfind('.');
string suffix(file.substr(pos, file.size()-pos));
cout << suffix << endl;
// npos是string裡面的一個靜態成員變數
// static const size_t npos = -1;
// 取出url中的域名
string url("http://www.cplusplus.com/reference/string/string/find/");
cout << url << endl;
size_t start = url.find("://");
if (start == string::npos)
{
cout << "invalid url" << endl;
return;
}
start += 3;
size_t finish = url.find('/', start);
string address = url.substr(start, finish - start);
cout << address << endl;
// 刪除url的協議字首
pos = url.find("://");
url.erase(0, pos+3);
cout<<url<<endl;
}
void TestPushBack()
{
string s;
size_t sz = s.capacity();
cout << "making s grow:\n";
for (int i = 0; i < 100; ++i)
{
s += 'c';
if (sz != s.capacity())
{
sz = s.capacity();
cout << "capacity changed: " << sz << '\n';
}
}
}
void TestPushBack_P()
{
string s;
s.reserve(100);
size_t sz = s.capacity();
cout << "making s grow:\n";
for (int i = 0; i < 100; ++i)
{
s += 'c';
if (sz != s.capacity())
{
sz = s.capacity();
cout << "capacity changed: " << sz << '\n';
}
}
}
注意:
1. 在string尾部追加字元時,s.push_back(c) / s.append(1, c) / s += 'c'三種的實現方式差不多,
一般 情況下string類的 += 操作用的比較多, += 操作不僅可以連線單個字元,還可以連線字串。
2. 對string操作時,如果能夠大概預估到放多少字元,可以先通過reserve把空間預留好。
幾個常見的筆試題
翻轉字串
string reverseString(string s)
{
if (s.empty())
return s;
size_t start = 0;
size_t end = s.size() - 1;
while (start < end)
{
swap(s[start], s[end]);
start++;
end--;
}
return s;
}
找字串中只出現一次的字元
int firstUniqueChar(string s)
{
//統計每個字元出現的次數
size_t array[256] = { 0 };
int size = s.size();
for (size_t i = 0; i < size; ++i)
{
array[s[i]] += 1;
}
//按照字元次序從前往後找只出現一次的字元
for (size_t i = 0; i < size; ++i)
{
if (array[s[i]] == 1)
{
return i;
}
}
return -1;
}
字串最後一個單詞的長度
#include <iostream>
#include <string>
using namespace std;
int _main()
{
string line;
while (getline(cin, line))
{
size_t pos = line.rfind(' ');
cout << line.size() - pos - 1 << endl;
}
return 0;
}
字串轉整型數字
字串的空格替換
字串相加
驗證是否為迴文
字串相乘