C++ 學習筆記之——字符串和字符串流

1. 字符數組

字符數組,也就是存放字符類型數據的數組,只不過字符數組的結尾必須是 '\0'。C++ 已經提供了一些字符串處理函數,這些函數被封裝在頭文件 和 <string.h> 中。ios

1.1. 字符串複製
  • void * memcpy ( void * destination, const void * source, size_t num ); 從 source 指針指向的內存拷貝 num 個字節到 destination 指針指向的內存;拷貝的是二進制數據,與兩個指針類型沒有關係;不檢查字符串結束符,只是拷貝對應字節的數據;兩個指針指向的數組大小至少都大於 num 個字節並且不該該有重疊。數組

  • void * memmove ( void * destination, const void * source, size_t num ); 和 memcpy 相似,只不過支持內存重疊,就好像是有一箇中間緩衝區同樣。app

  • char * strcpy ( char * destination, const char * source ); 將 source 指針指向的字符串拷貝到 destination 指針指向的數組,包括終止字符, destination 指針指向的數組必須有足夠的大小來容納待拷貝字符串,而且不支持內存重疊。函數

  • char * strncpy ( char * destination, const char * source, size_t num ); 將 source 指針指向的前 num 個字符串拷貝到 destination 指針指向的數組,不支持內存重疊。若是 source 字符串長度大於 num,那麼 destination 字符串將沒有終止字符;若是 source 字符串長度小於 num,那麼 destination 字符串會填充 0 直到總共有 num 個字符寫入。ui

#include <iostream>
#include <stdio.h>
#include <cstring>

using namespace std;

struct {
  char name[40];
  int age;
} person, person_copy;

int main () {
    char myname[] = "seniusen";

    /* 用 memcpy 拷貝字符串*/
    memcpy(person.name, myname, strlen(myname)+1);
    person.age = 22;

    /* 用 memcpy 拷貝結構體*/
    memcpy(&person_copy, &person, sizeof(person));

    printf("person_copy: %s, %d \n", person_copy.name, person_copy.age );

    /* memmove 支持重疊內存的拷貝*/
    char str[] = "seniusen works very hard.....!";
    memmove(str+20, str+15, 9);
    puts(str);

    return 0;
}
複製代碼

1.2. 字符串拼接
  • char * strcat ( char * destination, const char * source ); 將 source 指針指向的字符串拼接到 destination 指針指向的數組後,destination 的終止字符將被 source 的第一個字符覆蓋,同時拼接後的字符串末尾會添加一個終止字符,不支持內存重疊。spa

  • char * strncat ( char * destination, const char * source, size_t num ); 將 source 指針指向的前 num 個字符串拼接到 destination 指針指向的數組,不支持內存重疊。若是 source 字符串長度小於 num,那麼只拼接終止字符 '\0' 前面的內容。指針

1.3. 字符串比較
  • int strcmp ( const char * str1, const char * str2 ); 比較兩個字符串 str1 和 str2,從第一個字符開始比較,若是相同則繼續往下比較,直到遇到不一樣字符或者終止字符結束比較。code

  • int strncmp ( const char * str1, const char * str2, size_t num ); 和 strcmp 相似,只不過是直到遇到不一樣字符或者終止字符或者已經比較了 num 個字符串就結束比較。cdn

  • int memcmp ( const void * ptr1, const void * ptr2, size_t num ); 和 strcmp 相似,只不過是遇到終止字符不會結束比較對象

  • int strcoll ( const char * str1, const char * str2 ); 由當前所選 C 語言環境的 LC_COLLATE 類別來定義比較規則,好比漢字能夠按照拼音來比較。

  • size_t strxfrm ( char * destination, const char * source, size_t num ); 根據當前所選 C 語言環境的 LC_COLLATE 類別來轉換 source 指向的字符串,並將轉換後字符串的前 num 個字符複製到 destination,返回其長度。若是指定 destination 爲空指針,num 爲 0,此函數能夠返回字符串的長度。

1.4. 字符串搜索
  • const void * memchr ( const void * ptr, int value, size_t num ); 查找 ptr 指向內存的前 num 個字節,看是否存在 value,若是存在則返回指向它的指針,value 和 ptr 指向的數組都被轉化爲無符號字符型數據來進行比較。

  • const char * strchr ( const char * str, int character ); 查找 str 指向的字符數組中是否存在 character,若是存在則返回第一個指向它的指針,character 被轉化爲字符型數據來進行比較,終止字符也能夠被定位

  • const char * strrchr ( const char * str, int character ); 與 strchr 相似,只不過是返回最後一個指向它的指針

  • size_t strcspn ( const char * str1, const char * str2 ); 掃描在字符串 str1 中出現的第一個任意 str2 中的字符,返回找到時已經從 str1 中讀取的字符個數,包括終止字符的搜索,也就是說,若 str2 中沒有字符存在於str1 中,則返回 str1 的長度。

  • const char * strpbrk ( const char * str1, const char * str2 ); 掃描在字符串 str1 中出現的第一個任意 str2 中的字符,返回指向那個字符的指針,不包括終止字符的搜索但會在終止字符處結束,也就是說,若 str2 中沒有字符存在於str1 中,則返回空指針。

  • size_t strspn ( const char * str1, const char * str2 ); 返回字符串 str1 中只包含 str2 中字符的部分的長度。若是 str1 中第一個字符就不在 str2 中,則返回 0;若是 str1 中全部字符都在 str2 中,則返回 str1 的長度;

  • const char * strstr ( const char * str1, const char * str2 ); 掃描字符串 str2 在 str1 中第一次出現的位置,不包括終止字符的搜索但會在終止字符處結束。

  • char * strtok ( char * str, const char * delimiters ); 在字符串 str 中先找到第一個不在 delimiters 中的字符,也就是口令的起始位置,而後以此爲起點再繼續找到第一個位於 delimiters 中的字符,這是口令的結束位置。而後經過傳入一個 NULL 指針和新的 delimiters,函數會繼續從上一個口令結束位置的下一個字符繼續查找。

/* strtok example */
#include <stdio.h>
#include <string.h>

int main () {
  char str[] ="- This, a sample string.";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.-");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ,.-");
  }
  return 0;
}
複製代碼

1.5. 其它
  • size_t strlen ( const char * str ); 返回字符串的長度,也就是終止字符前面字符的個數。

  • void * memset ( void * ptr, int value, size_t num ); 將 ptr 指針指向內存區域前 num 個字節數據設置成 value,value 被轉化爲無符號字節型數據。

  • char * strerror ( int errnum ); 將 errnum 轉化爲描述錯誤狀況的字符串。

2. 字符串類

此外,爲了更方便地對字符串進行操做,C++ 中定義了一個 string 類,能夠在使用的時候包含頭文件 。

2.1. 構造函數
  • string(); 默認構造函數。

  • string (const string& str); 複製構造函數,定義一個對 str 進行復制的字符串。

  • string (const string& str, size_t pos, size_t len = npos); 以字符串 str 的 pos 位置開始長度爲 len 的子字符串進行構造。

  • string (const char* s); 從字符數組構造。

  • string (const char* s, size_t n); 從 s 指向內存的前 n 個字符構造。

  • string (size_t n, char c); 構造一個具備 n 個字符 c 的字符串。

  • template <class InputIterator> string (InputIterator first, InputIterator last); 以 [first,last) 區間的字符串進行構造。

此外,能夠用一個字符串類變量或者字符數組或者字符直接對字符串類變量進行賦值,兩個字符串變量拼接則能夠直接用加法來實現。

2.2. 迭代器
  • iterator begin(); 指向字符串第一個元素的迭代器。

  • iterator end(); 指向字符串最後一個元素後面位置的迭代器,若是字符串爲空,則與 begin() 相同。

  • reverse_iterator rbegin(); 指向字符串最後一個元素的反向迭代器。

  • reverse_iterator rend(); 指向字符串第一個元素前面位置的反向迭代器。

2.3. 容量
  • size_t size() const; 字符串的長度。

  • size_t length() const; 字符串的長度,與 size() 等價。

  • size_t max_size() const; 字符串理論上的最大程度。

  • void resize (size_t n, char c); 從新設置字符串爲 n 個字符的長度。若是 n 比現有字符串長度小,則只保留前 n 個字符;若是 n 比現有字符串長度大,則填充字符 c 或者 NULL。

  • size_t capacity() const; 返回字符串當前內存支持的最大長度,這個數字是動態變化的。

  • void reserve (size_t n = 0); 保證字符串至少能容納 n 個字符。

  • void clear(); 清空字符串的內容。

  • bool empty() const; 返回字符串是否爲空。

  • void shrink_to_fit(); 讓字符串的容量等於其長度。

2.4. 元素訪問
  • char& operator[] (size_t pos); 像數組同樣訪問位置 pos 處的字符。

  • char& at (size_t pos); 訪問位置 pos 處的字符,會檢查是否越界

  • char& front(); 返回字符串第一個字符。

  • char& back(); 返回字符串最後一個字符。

2.5. 修改字符串
2.6. 其它字符串操做

此外,字符串類還支持將字符串類變量轉化爲字符數組,在字符串中從前向後查找、從後向前查找等操做。更多方法見此

3. 字符串流

字符串流是以內存中的字符串類對象或者字符數組爲輸入輸出對象的數據流,也便是將數據輸出到字符串流對象或者從字符串流對象讀入數據,也稱之爲內存流。

  • explicit ostringstream (const string& str, ios_base::openmode which = ios_base::out); 創建輸出字符串流對象。
  • explicit istringstream (const string& str, ios_base::openmode which = ios_base::in); 創建輸入字符串流對象。
  • explicit stringstream (const string& str, ios_base::openmode which = ios_base::in | ios_base::out); 創建輸入輸出輸出字符串流對象。
#include <sstream>
#include <iostream>
#include <string>

using namespace std;

int main () {
    string str1 = "Hello, seniusen!";
    string str2(str1);

    ostringstream foo(str1);                  // 默認在字符串起始位置添加
    ostringstream bar(str2, ios_base::ate);  // 在字符串末尾位置添加


    foo << " Hi, seniusen! ";
    bar << " Well done!";

    cout << foo.str() << '\n';
    cout << bar.str() << '\n';

    istringstream strin(str1);
    string str3;

    strin >> str3; // 遇到空格中止插入
    cout << str3 << endl;

    // 生成一個文件名
    string str4;
    stringstream ss;

    ss << "/home/seniusen/";
    ss << 100;
    ss << "_noise_image_";
    ss << 15;
    ss << ".jpg";
    ss >> str4;

    cout << str4 << endl;

    return 0;
}
複製代碼

獲取更多精彩,請關注「seniusen」!

相關文章
相關標籤/搜索