C++之路 Day6

string類專題

      string是一個類,它有很多成員方法,我們平時開發也主要是關注string在字符串處理方面的用法。所以本文主要以代碼案例來說明其用法。以下案例涵蓋了string類的絕大數多數成員方法的使用,開發時可作爲手冊快速查詢。(代碼經過全面自測可直接使用


#include <iostream>
#include <string>
#include <cstring>  //比如要使用strcpy
#include <cstddef>  //std::size_t
#include <fstream>

using namespace std;

void SplitFilename(const string &str){
    cout<<"Splitting: "<<str<<'\n';
    size_t found = str.find_last_of("/\\");
    cout<<" path: "<<str.substr(0, found)<<'\n';    //目錄
    cout<<" file: "<<str.substr(found+1)<<'\n'; //文件名或最內層文件夾名
}

int main()
{
    //string的初始化
    string string_1("string 1");
    string string_2;
    string_2 = "string 2";
    //從標準輸入讀取一整行
    string string_3;
    getline(cin, string_3, '\n');

    //字符串還可以拼接
    string string_4 = string_1 + string_2 + string_3;
    cout<<string_4<<endl;

    string string_5;
    string_5 += "hello string 5";
    cout<<string_5<<endl;

    //字符串的比較
    string string_6;
    getline(cin, string_6, '\n');
    if(string_6 == "xyz"){
        cout<<"Access allowed"<<endl;
    }

    //求字符串的長度
    string string_7 = "my name is string 7";
    int len = string_7.length();    //or .size()
    cout<<len<<endl;    //19

    //訪問字符串的單個元素,就像訪問數組一樣
    for(int i = 0;i < string_7.size();i++){
        cout<<string_7[i]<<endl;
    }

    //使用string類型的迭代器訪問字符串的單個元素
    string::iterator iter;
    for(iter = string_7.begin(); iter != string_7.end();++iter){
        cout<<*iter<<endl;
    }

    //string類支持簡單的查詢和截取

    string string_8;
    getline(cin, string_8, '\n');
    int cat_find = 0;
    for(int i = string_8.find("cat", 0);i != string_8.npos;i = string_8.find("cat", i)){//string::npos, that indicates that it did not find the substring
        cat_find++;
        i++;
    }
    cout<<cat_find<<endl;

    string string_9 = "abcdefghijklabcdilj";
    string sub_string_9 = string_9.substr(1, 5);
    cout<<sub_string_9<<endl;   //bcdef

    //string的修改
    string string_A = "12345678";
    string_A.erase(3, 2);   //從位置3(包含位置3)往後去除2個元素
    cout<<string_A<<endl;   //123678

    //刪除整個字符串
    string string_B = "1232ljfasf";
    string_B.erase(0, string_B.length());

    //插入字符串到一個已經存在的字符串中
    string string_C = "abef";
    string_C.insert(2, "cd");
    cout<<string_C<<endl;   //abcdef

    //string類的成員方法用例
    //append 方法: Extends the string by appending additional characters at the end of its current value

    string str;
    string str2 = "Writing ";
    string str3 = "print 10 and then 5 more";

    str.append(str2);       //"Writing "
    str.append(str3, 6, 3); //"10 " 從str3的第6個位置截取3個字符
    str.append("dots are cool", 5); //"dots "   //默認從位置 0 開始截取5個字符
    str.append("here: ");   //"here: "
    str.append(10u,'.');    //".........."
    str.append(str3.begin()+8, str3.end()); //" and then 5 more"
    //str.append<int>(5, 0x2E);
    cout<<str<<endl;    //Writing 10 dots here: .......... and then 5 more

    //assign 方法: Assigns a new value to the string, replacing its current contents

    string str_A;
    string base = "The quick brown fox jumps over a lazy dog.";
    str_A.assign(base); //"The quick brown fox jumps over a lazy dog."
    cout<<str_A<<endl;
    str_A.assign(base, 10, 9);
    cout<<str_A<<endl;  //"brown fox"
    str_A.assign("pangrams are cool", 7);
    cout<<str_A<<endl;  //"pangram"
    str_A.assign("c-string");
    cout<<str_A<<endl;  //"c-string"
    str_A.assign(10, '*');
    cout<<str_A<<endl;  //"**********"
    str_A.assign(base.begin()+16, base.end()-12);   //從位置16到倒數12位置結束的這段
    cout<<str_A<<endl;  //"fox jumps over"

    //at 方法:Returns a reference to the character at position pos in the string

    string str_B("Test string");
    for(unsigned i = 0;i < str_B.length(); ++i){
        cout<<str_B.at(i);
    }

    //back 方法:Returns a reference to the last character of the string

    string str_C("hello world");
    str_C.back() = '!'; //替換原始字符串中的最後一個字符
    cout<<str_C<<endl;  //"hello worl!"

    //begin 方法:Returns an iterator pointing to the first character of the string.
    for(string::iterator iter = str_C.begin(); iter != str_C.end();++iter){
        cout<<*iter<<endl;
    }

    //capacity 方法:Returns the size of the storage space currently allocated for the string
    //This capacity is not necessarily equal to the string length. It can be equal or greater, with the extra space allowing the object to optimize its operations when new characters are added to the string
    //The capacity of a string can be explicitly altered by calling member reserve
    cout<<"size: "<<str_C.size()<<endl; //11
    cout<<"length: "<<str_C.length()<<endl; //11
    cout<<"capacity: "<<str_C.capacity()<<endl; //15
    cout<<"max_size: "<<str_C.max_size()<<endl; //9223372036854775807

    //cbegin, cend 方法:它跟 begin 方法類似都是返回一個 iterator.只是這個方法無條件返回 const_iterator
    string str_D("Lorem ipsum");
    for(auto it = str_D.cbegin();it != str_D.cend();++it){
        cout<<*it<<endl;
    }

    //clear 方法:Erases the contents of the string, which becomes an empty string (with a length of 0 characters).
    char c;
    string str_E;
    cout<<"Please type some lines of text.Enter a dot(.) to finish:\n";
    do{
        c = cin.get();
        str_E += c;
        if(c=='\n'){
            cout<<str_E;
            str_E.clear();
        }
    }while(c!='.');

    //compare 方法: 字符串的比較
    string str_F("green apple");
    string str_G("red apple");

    if(str_F.compare(str_G) != 0){
        cout<<str_F<<" is not "<<str_G<<'\n';
    }
    if(str_F.compare(6, 5, "apple") == 0){  //從字符串str_F的第 6 個位置往後的連續5個字符
        cout<<"still, "<<str_F<<" is an apple\n";
    }
    if(str_G.compare(str_G.size()-5, 5, "apple") == 0){ //從字符串str_G的第 4 個位置往後的連續5個字符
        cout<<"and "<<str_G<<" is also an apple\n";
    }
    if(str_F.compare(6, 5, str_G, 4, 5) == 0){
        cout<<"therefore, both are apples\n";
    }

    //copy 方法:Copy sequence of characters from string,The function does not append a null character at the end of the copied content
    //賦值後的字符串需要手動在末尾添加'\0'
    char buffer[20];
    string str_H("Test string...");
    size_t length = str_H.copy(buffer, 6, 5);
    buffer[length] = '\0';
    cout<<"buffer contains: "<<buffer<<'\n';

    //rbegin, rend方法:Return reverse iterator to reverse beginning
    string str_Ii = "now step live...";
    for(string::reverse_iterator rit = str_Ii.rbegin();rit != str_Ii.rend();++rit)
        cout<<*rit;
    cout<<'\n'; //...evil pets won

    //crbegin , crend方法:Returns a const_reverse_iterator pointing to the last character of the string
    //反向的起點
    string str_I("lorem ipsum");
    for(auto rit = str_I.crbegin();rit != str_I.crend();++rit){
        cout<<*rit;
    }
    cout<<'\n'; //muspi merol

    //c_str 方法:Returns a pointer to an array that contains a null-terminated sequence of characters
    //This array includes the same sequence of characters that make up the value of the string object plus an additional terminating null-character ('\0') at the end
    string str_J("Please split this sentence into tokens");
    char *cstr = new char[str_J.length()+1];
    strcpy(cstr, str_J.c_str());

    // cstr now contains a c-string copy of str_J

    char *p = strtok(cstr, " ");
    while(p!=0){
        cout<<p<<'\n';
        p = strtok(NULL, " ");
    }
    delete[] cstr;

    //data 方法:Return a pointer to the c-string representation of the string object's value
    int length_K;
    string str_K = "Test string";
    char *cstr_k = "Test string";   //C++11 不支持string 到 char *的轉換,可以編譯通過但會warn

    if( str_K.length() == strlen(cstr_k)){
        cout<<"str_K and cstr_k have the same length.\n";
        if(memcmp(cstr_k, str_K.data(), str_K.length()) == 0){
            cout<<"str_K and cstr_k have the same content.\n";
        }
    }

    //empty 方法:Test if string is empty,Returns whether the string is empty,true if the string length is 0, false otherwise
    string content;
    string line;
    cout<<"Please introduce a text. Enter an empty line to finish:\n";
    do{
        getline(cin, line);
        content += line + '\n';
    }while(!line.empty());
    cout<<"The text you introduced was:\n"<<content;

    //find 方法:Searches the string for the first occurrence of the sequence specified by its arguments
    //全詞匹配
    string str_L("There are two needls in this haystack with needles.");
    string str_M("needls");

    //different member versions of find in the same order as above:
    size_t found = str_L.find(str_M);
    if(found != string::npos)
        cout<<"first 'needle' found at: "<<found<<'\n';
    found = str_L.find("needles are small", found+1, 6);    //意思是從str_L的第 15 個位置開始找出連續6個字符與"needles are small"有交集的子字符串,並返回這個子字符串的起始位置
    if(found != string::npos)
        cout<<"second 'needls' found at: "<<found<<'\n';
    found = str_L.find("haystack");
    if(found != string::npos)
        cout<<"'haystack' also found at: "<<found<<'\n';

    found = str_L.find('.');
    if(found != string::npos)
        cout<<"Period found at: "<<found<<'\n';

    //rfind 方法:Searches the string for the last occurrence of the sequence specified by its arguments
    string str_Li("The sixth sick sheik's sixth sheep's sick.");
    string key("sixth");

    size_t found_li = str_Li.rfind(key);
    if(found != string::npos)
        str_Li.replace(found_li, key.length(), "seventh");
    cout<<str_Li<<'\n'; //The sixth sick sheik's seventh sheep's sick.

    //下面有幾個方法可以用到加密解密裏面
    //find_first_not_of 方法:Searches the string for the first character that does not match any of the characters specified in its arguments
    //找到一個與匹配字符串任何字符都不匹配的字符的位置

    string str_N("look for non-alphabetic characters...");
    size_t found_N = str_N.find_first_not_of("abcdefghijklmnopqrstuvwxyz ");

    if(found_N != string::npos){
        cout<<"The first non-alphabetic character is "<<str_N[found_N]; //'-'
        cout<<" at position "<<found_N<<'\n';
    }

    //find_first_of 方法:Searches the string for the first character that matches any of the characters specified in its arguments
    string str_O("Please, replace the vowels in this sentence by asterisks.");
    size_t found_O = str_O.find_first_of("aeiou");
    while(found_O != string::npos){
        str_O[found_O] = '*';
        found_O = str_O.find_first_of("aeiou", found_O+1);
    }
    cout<<str_O<<'\n';  //Pl**s*, r*pl*c* th* v*w*ls *n th*s s*nt*nc* by *st*r*sks.

    //find_last_not_of 方法: Find non-matching character in string from the end
    string str_P("Please, erase trailing white-spaces    \n");
    string whitespaces(" \t\f\v\n\r");

    size_t found_p = str_P.find_last_not_of(whitespaces);
    if(found_p != string::npos)
        str_P.erase(found_p+1); //刪掉非空格 等 字符 後面的所有字符
    else
        str_P.clear();
    cout<<str_P<<endl;  //"Please, erase trailing white-spaces"

    //find_last_of 方法: Searches the string for the last character that matches any of the characters specified in its arguments.
    string str_Q("/usr/bin/man");
    string str_R("D:\androidSDK\\emulator\\emulator.exe");
    SplitFilename(str_Q);
    SplitFilename(str_R);

    //front 方法: Access first character.Returns a reference to the first character of the string
    //Unlike member string::begin, which returns an iterator to this same character, this function returns a direct reference.
    //This function shall not be called on empty strings
    string str_S("test string");
    str_S.front() = 'T';
    cout<<str_S<<endl;  //Test string

    //pop_back 方法:Erases the last character of the string, effectively reducing its length by one
    string str_T("hello world!");
    str_T.pop_back();
    cout<<str_T<<endl;  //hello world
    cout<<str_T.length()<<endl; //11

    //push_back 方法:Appends character c to the end of the string, increasing its length by one
    string str_U;
    ifstream file("F:\\QtProj\\string_demo\\text.txt", ios::in);
    if(file.is_open()){
        //cout<<"ok..."<<endl;
        while(!file.eof())
            str_U.push_back(file.get());    //挨個字節文件數據寫到str_U字符串中
    }
    cout<<str_U<<endl;  //文件內容

    //replace 方法:Replaces the portion of the string that begins at character pos and spans len characters
    //替換從字符位置開始並跨越 len 長度字符的字符串部分
    string base = "this is a test string";
    string str_V1 = "n example";
    string str_V2 = "sample phrase";
    string str_V3 = "userful.";

    string str_W = base;
    str_W.replace(9, 5, str_V1);    //將base字符串從第九個位置開始往後的連續5個位置的字符替換爲str_V1
    cout<<str_W<<endl;  //this is an example string
    str_W.replace(19, 6, str_V2, 7, 6); //將str_V2字符串的第7個位置往後的連續6個字符替換到str_W字符串的第19個位置往後的連續6個字符的位置
    cout<<str_W<<endl;  //this is an example phrase
    str_W.replace(8, 10, "just a");
    cout<<str_W<<endl;  //this is just a phrase
    str_W.replace(8, 6, "a shorty", 7); //將字符串"a shorty"中從0開始往後7個字節長度的部分替換到str_W的第8個字節開始往後的連續6個字符的位置
    cout<<str_W<<endl;  //this is a short phrase
    str_W.replace(22, 1, 3, '!');
    cout<<str_W<<endl;  //this is a short phrase!!!

    //Using iterators:
    str_W.replace(str_W.begin(), str_W.end()-3, str_V2);
    cout<<str_W<<endl;  //sample phrase!!!
    str_W.replace(str_W.begin(), str_W.begin()+6, "replace");
    cout<<str_W<<endl;  //replace phrase!!!
    str_W.replace(str_W.begin()+8, str_W.begin()+14, "is coolness", 7); //7表示從 is coolness中從頭開始取7個長度字符
    cout<<str_W<<endl;  //replace is cool!!!
    str_W.replace(str_W.begin()+12, str_W.end()-4, 4, 'o');
    cout<<str_W<<endl;  //replace is cooool!!!
    str_W.replace(str_W.begin()+11, str_W.end(), str_V3.begin(), str_V3.end());
    cout<<str_W<<endl;  //replace is userful.

    //reserve 方法:Request a change in capacity
    string str_X;
    ifstream file_x("F:\\QtProj\\string_demo\\text.txt", ios::in|ios::ate);
    if(file_x.is_open()){
        ifstream::streampos filesize = file_x.tellg();
        str_X.reserve(filesize);

        file_x.seekg(0);
        while(!file_x.eof()){
            str_X += file_x.get();
        }
        cout<<str_X<<endl;
    }

    //resize 方法:Resizes the string to a length of n characters
    string str_y("I like to code in C");
    cout<<str_y<<'\n';

    unsigned sz = str_y.size();
    str_y.resize(sz+2, '+');
    cout<<str_y<<endl;  //I like to code in C++
    str_y.resize(14);
    cout<<str_y<<endl;  //I like to code

    //shrink_to_fit 方法:Requests the string to reduce its capacity to fit its size
    //請求字符串減小其容量以適合其大小
    //This function has no effect on the string length and cannot alter its content
    string str_z(100, 'x');
    cout<<str_z<<endl;
    cout<<"1. capacity of str_z: "<<str_z.capacity()<<'\n'; //1. capacity of str_z: 100
    str_z.resize(10);
    cout<<"2. capacity of str_z: "<<str_z.capacity()<<'\n'; //2. capacity of str_z: 100
    str_z.shrink_to_fit();
    cout<<"3. capacity of str_z: "<<str_z.capacity()<<'\n'; //3. capacity of str_z: 15

    //swap 方法:Exchanges the content of the container by the content of str, which is another string object. Lengths may differ
    string buyer("money");
    string seller("goods");

    cout<<"Before the swap,buyer has "<<buyer;
    cout<<" and seller has "<<seller<<'\n';

    seller.swap(buyer);

    cout<<"After the swap, buyer has "<<buyer;
    cout<<" and seller has "<<seller<<'\n';

    return 0;
}

參考:https://www.cprogramming.com/tutorial/string.html

http://www.cplusplus.com/reference/string/string/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章