【C/C++】从API学习 string 库(第3部分)

 string 概述

  • String objects are a special type of container, specifically designed to operate with sequences of characters.
  • Unlike traditional c-strings, which are mere sequences of characters in a memory array, C++ string objects belong to a class with many built-in features to operate with strings in a more intuitive way and with some additional useful features common to C++ containers.
  • 字符串对象是一种特殊的容器专门用于操作字符序列
  • 与仅仅是内存数组中的字符序列的传统C字符串不同,c++字符串对象属于这样一个类,它具有许多内置特性,可以以更直观的方式操作字符串,还具有一些c++容器共有的有用特性。

 

string类成员函数 (Member Functions)

7 String operations (字符串操作)

  7.1 string::compare 先看这个 字符串的比较很多地方用到

compare函数概述:

compare函数声明:

// 函数声明 参数是什么意思?怎么用?看了API说明就会有答案
int compare ( const string& str ) const; // str是要被原字符串比较的字符串

int compare ( const char* s ) const; // 字符数组名(数组字符以'\0'结尾)

int compare ( size_t pos1, size_t n1, const string& str ) const; // Origin[pos1, pos1+n1) 参与 与str的比较

int compare ( size_t pos1, size_t n1, const char* s) const; // Origin[pos1, pos1+n1) 参与 与str的比较

// Origin[pos1, pos1+n1)与str[pos2, pos2+n2)比较
int compare ( size_t pos1, size_t n1, const string& str, size_t pos2, size_t n2 ) const;

// Origin[pos1, pos1_n1)与s的前n个字符进行比较
int compare ( size_t pos1, size_t n1, const char* s, size_t n2) const;

以下是对参数的说明:

 函数return的规则:

演示与功能验证:

/**
 * Created By Liu Xianmeng On 2022/12/6
 * 官方给的例子真的太妙啦!
 */
#include <bits/stdc++.h>
using namespace std;
int main(){
    string str1 ("green apple");
    string str2 ("red apple");
    if (str1.compare(str2) != 0)
        cout << str1 << " is not " << str2 << "\n"; 
    if (str1.compare(6,5,"apple") == 0)
        cout << "still, " << str1 << " is an apple\n";
    if (str2.compare(str2.size()-5,5,"apple") == 0)
        cout << "and " << str2 << " is also an apple\n";
    if (str1.compare(6,5,str2,4,5) == 0)
        cout << "therefore, both are apples\n";
    /* 【打印结果】
        green apple is not red apple
        still, green apple is an apple
        and red apple is also an apple
        therefore, both are apples
     */
    return 0;
}

  7.2 string::str_c 生成一个字符数组字符串 自动追加''

  • Generates a null-terminated sequence of characters (c-string) with the same content as the string object and returns it as a pointer to an array of characters.
  • A terminating null character is automatically appended. // 自动追加一个'\0'
  • The returned array points to an internal location with the required storage space for this sequence of characters plus its terminating null-character, but the values in this array should not be modified in the program and are only granted to remain unchanged until the next call to a non-constant member function of the string object.
  • 生成一个以空字符结尾的字符序列(c-string),其内容与string对象相同,并将其作为指向字符数组的指针返回
  • 简单总结:这个函数就是返回了一个字符数组的首地址,字符数组存储的是原字符串的内容,其末尾以'\0'结束
/**
 * Created By Liu Xianmeng On 2022/12/7
 */
#include <bits/stdc++.h>
using namespace std;
int main(){
    char *cstr, *p;
    string str ("Please split this phrase into tokens");
    cstr = new char [str.size()+1];
    // 让cstr指针指向str.c_str()返回的字符数组的首地址
    strcpy (cstr, str.c_str());
    // cstr now contains a c-string copy of str
    p=strtok (cstr," "); // 对cstr进行分割, 分隔符为 ' '
    while (p!=NULL) // 当p不为空 连续打印分割单词
    {
        cout << p << endl; // 输出当前的分割单词并换行
        p=strtok(NULL," "); // 后续分割str传入NULL
    }
    delete[] cstr; // 释放对象数组指针指向的内存
    /*  
       【打印结果】
        Please
        split
        this
        phrase
        into
        tokens
     */
    return 0;
}

  7.3 string::data 返回一个原string内容的复制数组(不追加'\0')

  • Returns a pointer to an array of characters with the same content as the string.
  • Notice that no terminating null character is appended (see member c_str for such a functionality).
  • The returned array points to an internal location which should not be modified directly in the program. Its contents are guaranteed to remain unchanged only until the next call to a non-constant member function of the string object.
  • 返回一个原string内容的复制数组(不追加'\0'),顾名思义,获取字符串的数据(内容与原字符完全一致)
/**
 * Created By Liu Xianmeng On 2022/12/7
 */
#include <bits/stdc++.h>
using namespace std;
int main(){
    int length;
    string str = "Test string";
    char* cstr = "Test string";
    if ( str.length() == strlen (cstr) ){
        cout << "str and cstr have the same length.\n";
        length = str.length();
        // 内存比较 str.data()获取str的字符串内容(不追加'\0')并与cstr内容进行比较
        if ( memcmp (cstr, str.data(), length ) == 0 ){
            cout << "str and cstr have the same content.\n";
        }
    }
    /*
       【打印结果】
        str and cstr have the same length.
        str and cstr have the same content.
     */
    return 0;
}

   7.4 string::copy 拷贝字符串的内容

size_t copy ( char* s, size_t n, size_t pos = 0) const;

其实看API到这这里,大家就适应了API的结构和模型(很多参数的构造都是通用的,很容易变通),所以读API开始可能有点困难,但是熟练了就比较轻松和顺利了~ 比如上面这个size_t 一看就知道是字符长度的意思,而pos就是字符串的字符下标

/**
 * Created By Liu Xianmeng On 2022/12/7
 */
#include <bits/stdc++.h>
using namespace std;
int main(){
    size_t length;
    char buffer[20];
    string str ("Test string...");
    // 把str从下标为5的字符开始连续拷贝6个字符到buffer数组
    length = str.copy(buffer,6,5);
    // 没有追加'\0'打印会出乱码?不会/笑哭 因为buffer在声明的时候默认就存的是'\0'
    cout << "buffer contains: " << buffer << "\n";
    buffer[length]='\0'; // 追加一个'\0'便于打印不出乱码
    cout << "buffer contains: " << buffer << "\n";
    return 0;
    /*
       【打印结果】
        buffer contains: string
        buffer contains: string
     */
    return 0;
}

  7.5 string::find 内容查找

/* 
 * [INSTRUCTION] 
 * size_t pos = 0 是什么意思?pos参数默认为0 也就是从第一个字符开始
 * 如果参数n不传入 则默认n===str.size() 即在原字符串中查找str整个字符串
 * 如果n传入 则是在原字符串中查找str[pos, n)范围的字符串
 * s是字符数组名,可以等同看做是str
 * c即在原字符串中查找单个字符
 * Return Value:
 * The position of the first occurrence in the string of the searched content.
 * If the content is not found, the member value npos is returned.
 */
size_t find ( const string& str, size_t pos = 0 ) const;
size_t find ( const char* s, size_t pos, size_t n ) const;
size_t find ( const char* s, size_t pos = 0 ) const;
size_t find ( char c, size_t pos = 0 ) const;

返回值提到一个string的静态成员 npos,如果查找失败会返回npos,那npos是什么呢?

static const size_t npos = -1;

Maximum value for size_t  // size_t的最大值18446744073709551615

npos is a static member constant value with the greatest possible value for an element of type size_t.
This value, when used as the value for a count parameter n in string's member functions, roughly indicates "as many as possible".
When used in some pos parameters that allow for out-of-range values, npos indicates the end of the string.
As a return value it is usually used to indicate failure. 用来表示【失败】的含义


This constant is actually defined with a value of -1 (for any trait), 这个常数通常定义为-1 which because size_t is an unsigned integral type, becomes the largest possible representable value for this type(为什么?这没看懂 ̄へ ̄ 为什么不一直是-1 emm).  // 即 18446744073709551615

 npos的值演示:

string str("BigXMeng");
cout<<str.max_size()<<endl;
cout<<str.find("jinxuan"); // str中找不到"jinxuan" 即打印npos的值18446744073709551615 
/*
   【打印结果】
    4611686018427387903  // str.max_size()
    18446744073709551615 // Maximum value for size_t
 */

string::find函数功能演示:

/**
 * Created By Liu Xianmeng On 2022/12/7
 */
#include <bits/stdc++.h>
using namespace std;
int main() {
    string str("There are two needles in this haystack with needles.");
    string str2("needle");
    size_t found;
    // different member versions of find in the same order as above:
    found = str.find(str2);
    if (found != string::npos)
        cout << "first 'needle' found at: " << int(found) << endl;
    found = str.find("needles are small", found + 1, 6);
    if (found != string::npos)
        cout << "second 'needle' found at: " << int(found) << endl;
    found = str.find("haystack");
    if (found != string::npos)
        cout << "'haystack' also found at: " << int(found) << endl;
    found = str.find('.');
    if (found != string::npos)
        cout << "'.' found at: " << int(found) << endl;
    // let's replace the first needle:
    str.replace(str.find(str2), str2.length(), "preposition");
    cout << str << endl;
    return 0;
    /*
       【注意】
         find函数的第一个参数既可以是字符串本身,也可以是字符数组的数组名
       【打印结果】
         first 'needle' found at: 14
         second 'needle' found at: 44
         'haystack' also found at: 30
         '.' found at: 51
         There are two prepositions in this haystack with needles.
     */
}

  7.6 string::rfind 内容查找

  • 用法参照find
  • 查找原字符串中最后一次出现查找目标的pos(位置),返回pos
  • 如果没找到,返回npos的值

7.7 string::find_first_of 返回目标字符串中的任一第一次在原字符串里出现的字符的位置

  • 目标字符串就是传入的要查找的字符串(实际上是要查找其包含的字符并返回其下标)
  • 这里所说的目标字符串(传入的参数,与正则表达式非常相似)
/**
 * Created By Liu Xianmeng On 2022/12/7
 */
#include <bits/stdc++.h>
using namespace std;
int main() {
    string str ("Replace the vowels in this sentence by asterisks.");
    size_t found;
    found=str.find_first_of("aeiou");
    // 循环查找 将str中的aeiou字母替换为*
    while (found!=string::npos){
        str[found]='*';
        found=str.find_first_of("aeiou",found+1);
    }
    cout << str << endl;
    return 0;
    /*
       【打印结果】
        R*pl*c* th* v*w*ls *n th*s s*nt*nc* by *st*r*sks.
     */
}

  7.8 string::find_last_of

  • 与find_first_of作用相同,都是查找字符,但find_last_of是从原字符串的末尾位置开始查找
  • 这个从末尾查找的功能在哪里能用到?分割路径和文件名(典型)-> 末尾的第一个斜杠刚好是文件夹名和文件名的中间分隔符
/**
 * Created By Liu Xianmeng On 2022/12/7
 */
#include <bits/stdc++.h>
using namespace std;
void SplitFilename (const string& str){
    size_t found;
    cout << "Splitting: " << str << endl;
    // 在原字符串中查找第一个'/'或者'\'(先找'/'找到即返回 没找到再找'\')
    found=str.find_last_of("/\\"); 
    // 获取文件夹名folder
    cout << " folder: " << str.substr(0,found) << endl; // [0,found)
    // 获取文件名file
    cout << " file: " << str.substr(found+1) << endl; // [found+1,end)不包含斜杠
}
int main (){
    string str1 ("/usr/bin/man");
    string str2 ("c:\\windows\\winhelp.exe");
    SplitFilename (str1);
    SplitFilename (str2);
    return 0;
    /*
       【打印结果】
        Splitting: /usr/bin/man
         folder: /usr/bin
         file: man
        Splitting: c:\windows\winhelp.exe
         folder: c:\windows
         file: winhelp.exe
     */
}

  7.9 string::find_first_not_of  返回str中第一个在查找目标字符串中不存在的字符

/**
 * Created By Liu Xianmeng On 2022/12/7
 */
#include <bits/stdc++.h>
using namespace std;
int main (){
    string str ("look for non-alphabetic characters...");
    size_t found;
    // 查找str中在"abcdefghijklmnopqrstuvwxyz "中不存在的字符
    // 显然 字符 '-' 不再"abcdefghijklmnopqrstuvwxyz "中,查找到的位置下标是12
    found = str.find_first_not_of("abcdefghijklmnopqrstuvwxyz ");
    if (found!=string::npos){
        cout << "First non-alphabetic character is " << str[found];
        cout << " at position " << int(found) << endl;
    }
    return 0;
    /*
       【打印结果】
        First non-alphabetic character is - at position 12
     */
}

  7.10 string::find_last_not_of

 返回str中第一个在查找目标字符串中不存在的字符(从str的末尾开始查找并返回结果

/**
 * Created By Liu Xianmeng On 2022/12/7
 */
#include <bits/stdc++.h>
using namespace std;
int main (){
    string str ("erase trailing white-spaces   \n");
    string whitespaces (" \t\f\v\n\r");
    size_t found;
    // 下面代码的功能是清除行末的这些字符: / \t\f\v\n\r/
    found=str.find_last_not_of(whitespaces);
    if (found!=string::npos)
        str.erase(found+1);
    else
        str.clear();            // str is all whitespace
    cout << '"' << str << '"' << endl;
    return 0;
    /*
       【打印结果】
        "erase trailing white-spaces"
     */
}

  7.10 string::substr 获取子字符串

/*
 * 传入的参数可以对pos和n进行覆盖
 * 也可以不传入参数 不传参数则得到一个和原字符串一样的字符串
 */
string substr ( size_t pos = 0, size_t n = npos ) const;
/**
 * Created By Liu Xianmeng On 2022/12/7
 */
#include <bits/stdc++.h>
using namespace std;
int main (){
    string str = "BigXmeng";
    string sub1 = str.substr(); // 得到和str一样的字符串
    string sub2 = str.substr(3); // 获取str[3,end)
    string sub3 = str.substr(3, 3); // 获取str[3,3+3)
    cout<<sub1<<endl;
    cout<<sub2<<endl;
    cout<<sub3<<endl;
    /*
       【打印结果】
        BigXmeng
        Xmeng
        Xme
     */
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值