iT邦幫忙

1

【c++標準函式庫(STL)筆記】string介紹 (含常見功能: 數字、字串互轉,字串切割,找子字串)

c++

今天學習c++裡面的string工具,
感覺蠻實用的,筆記一下

string簡介

string是一個字元陣列,
與C語言原生的char[]相比,
string有overload 許多運算子,如
+、+=、<、=、[]、<<、>>
使用上更為直覺

一、引入函式庫

要使用map,需要在程式開頭加入這兩行

#include <string>
using namespace std;

二、宣告

string的宣告方式如下:

string s;

宣告的同時初始化

初始化有以下幾種方式:

string s2(s1); //s2複製字串s1
string s2 = s1; //string s2(s1);
string s3("someString"); //s3是"someString",亦可寫string s3 = "someString"
string s4(5, 'c'); //s4是"ccccc"

三、存取元素/運算子

  • s[i] (或寫s.at(i))- 存取字串裡index為 i 的字元。(第一個字元的index為0)
  • s.front() - 回傳字串第一個字元。
  • s.back() - 回傳字串最後一個字元。
  • +- 用來串接字串 (串接字串時,開始的兩項需至少有一個為string,例如string s = "Hello " + "World";會錯)
  • >, <, == - 字串比大小,順序為字典順序

四、插入/刪除元素

  • s.push_back() - 新增元素至字串的尾端。
  • s.pop_back() - 刪除字串最尾端的元素。
  • s.insert() - 插入一個或多個元素至字串內的任意位置。
  • s.erase() - 刪除字串中一個或多個元素。
  • s.clear() - 清空字串。

五、取得或改變字串大小

  • s.empty() - 如果字串內部為空,則傳回 true 值,否則為false
  • s.size() - 取得字串目前的字元個數。
  • s.resize() - 改變字串目前的字元個數。

字串的常用情境

介紹幾個常見的字串處理技巧:
有時候,將數字當做做字串處理會很方便(或將字串轉數字處理),
這邊要教字串和數字如何互轉

數字轉字串

上網查到c++11新增的to_string函數,
功能非常強大,定義在namespace std裡面,
不論是轉換int,長整數,無號數,浮點數,通通都可以哦

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);

使用範例:

#include <iostream>
#include <string>
using namespace std;

int main()
{
    int n = 352;
    string s = to_string(n);
    cout << n + 2 << endl; //354
    return 0;
}

字串轉數字

在c語言中,可以透過<stdlib.h>裡面的atoi函數,
將一個字串轉換成整數,範例:

#include <iostream>
#include <stdlib.h>
using namespace std;

int main()
{
    char str[] = "123";
    cout << atoi(str) + 10 << endl; //印出133
    return 0;
}

那為什麼改寫成c++版本的string就不能用了呢?
(註: 在c++中引入C 語言的標準函式庫,只要在前面加上 c 然後去掉 .h即可,譬如說<stdlib.h>就變成<cstdlib>)

#include <iostream>
#include <cstdlib> 
#include <string>
using namespace std;

int main()
{
    string str = "123";
    cout << atoi(str) + 10 << endl;
    return 0;
}

錯誤訊息: cannot convert ‘std::string {aka std::basic_string}’ to ‘const char*’ for argument ‘1’ to ‘int atoi(const char*)’

研究了一下之後發現,函數atoi必須吃一個char陣列,
不能直接吃string,
解決的方法也很簡單,
C++ 的 string 函式庫中提供了 c_str() 函數,
只要在字串變數後面加上 c_str() 便能將 string 型態轉換成原生的 char 型態,
附上可以成功轉換的程式碼:

#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;

int main()
{
    string str = "123";
    cout << atoi(str.c_str()) + 10 << endl;
    return 0;
}

字串切割

另外,學習如何以指定的分割符將字串分割
譬如說我想把,| 當作字串的分割字元,
輸入字串15,||12 ,,AB 19
應該回傳{"15", "12", "AB", "19"}

關鍵會用到c++字串函數find_first_of

字串函數: find_first_of

使用的方式為s.find_first_of(splitSep(字串), pos(整數))
意思是從字串s的第pos個位置開始找起,
回傳出現splitSep的第一個位置(出現在splitSep中的任何一個字元就算出現),
若找不到則回傳-1

字串分割的程式碼如下:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

//函數功能: 傳入一個字串s,以splitSep裡的字元當做分割字符,回傳vector<string>
vector<string> splitStr2Vec(string s, string splitSep)
{
    vector<string> result;
    int current = 0; //最初由 0 的位置開始找
    int next = 0;
    while (next != -1)
    {
        next = s.find_first_of(splitSep, current); //尋找從current開始,出現splitSep的第一個位置(找不到則回傳-1)
        if (next != current)
        {
            string tmp = s.substr(current, next - current);
            if(!tmp.empty())  //忽略空字串(若不寫的話,尾巴是多個分割符的情形會錯)
            {
                result.push_back(tmp);
            }
        }
        current = next + 1; //下次由 next + 1 的位置開始找起。
    }
    return result;
}

int main()
{
    string s = " 15,||12 ,,AB 19";
    vector<string> sep = splitStr2Vec(s, " ,|");
    for (string t : sep)
        cout << t << endl;
}

尋找子字串

#include <iostream>
#include <string>
using namespace std;

int main()
{
    string s = "ag556561hgiu";
    cout <<s.find("56")<<endl; //回傳第一個找到的子字串位置,若找不到則回傳-1
    return 0;
}

結果:
3

參考資料

  1. Mr. Opengate. C/C++ - String 用法與心得完全攻略
  2. cplusplus.com- string
  3. C++ string 型態轉 int
  4. [程式設計] C++ 的字串切割

尚未有邦友留言

立即登入留言