C++string(一)

一.大体介绍

首先,我们先来翻译string的介绍内容,以便大家理解:

Strings are objects that represent sequences of characters

翻译:string是表示字符对象的容器

The standard string class provides support for such objects with an interface similar to that of a standard container of bytes, but adding features specifically designed to operate with strings of single-byte characters.

翻译:标准string类提供了类似一些标准容器对象的接口,但是添加一些特殊的内容需要operator+单个操作符。

The string class is an instantiation of the basic_string class template that uses char (i.e., bytes) as its character type, with its default char_traits and allocator types (see basic_string for more info on the template).

翻译:string类是基于  basic_string 模版的实例化,通过使用char类型来作为其字符类型,其默认是char_traits和allocator类型

Note that this class handles bytes independently of the encoding used: If used to handle sequences of multi-byte or variable-length characters (such as UTF-8), all members of this class (such as length or size), as well as its iterators, will still operate in terms of bytes (not actual encoded characters).

着重强调该类型是解决一个个独立的编码使用的,如果其用来解决多字节或可变字节字符串,所有的该类,也包括其迭代器,都是按字节操作

二.Member functions(成员函数)

1.构造函数(包括拷贝构造)

Constructs a string object, initializing its value depending on the constructor version used:
翻译:构造一个string类对象,初始化其值依赖其构造函数的使用!

string();
//Constructs an empty string, with a length of zero characters.
//翻译:构造一个空string类,并且有0个字符
string (const string& str);
//Constructs a copy of str.
//构造拷贝string到str
string (const string& str, size_t pos, size_t len = npos);
//Copies the portion of str that begins at the character position pos and spans len //characters (or until the end of str, if either str is too short or if len //isstring::npos).
//翻译:拷贝从pos位置开始到len个长度字节,如果不到len长度,就提前结束,npos默认为-1

string (const char* s);
//Copies the null-terminated character sequence (C-string) pointed by s.
//拷贝s中全部字符序列
string (const char* s, size_t n);
//Copies the first n characters from the array of characters pointed by s.
//翻译:从字符数组s中第一个字符开始拷贝n个字符
string(size_t n, char c);
//Fills the string with n consecutive copies of character c.
//翻译:将n个字符c连续不断的拷贝到string对象中
#include <string>
int main()
{
    //使用举例:
    string s0("hello string");        
    string s1; //string();
    std::string s2(s0);//string(const string & str);
    std::string s3(s0, 8, 3);//string(const string & str, size_t pos, size_t len = npos);
    std::string s4("A character sequence");//string(const char* s);
    std::string s5("Another character sequence", 12);//string(const char* s, size_t n);
    std::string s6(10, 'x');//string(size_t n, char c);
    cout << "s1:" << s1 << endl;
    cout << "s2:" << s2 << endl;
    cout << "s3:" << s3 << endl;
    cout << "s4:" << s4 << endl;
    cout << "s5:" << s5 << endl;
    cout << "s6:" << s6 << endl;
    return 0;
}

2.析构函数

析构函数不需要我们实现,类会默认实现

3.string::operator=(赋值重载)

Assigns a new value to the string, replacing its current contents.
翻译:给string指定新的内容来替换其当前内容

string& operator= (const string& str);
//将str对象的内容拷贝一份到目标类对象中	
string& operator= (const char* s);
//将指针s指向的内容拷贝一份到目标类对象中
string& operator= (char c);
//将c的内容拷贝一份到目标类对象中

举例:

#include <string>
int main()
{
    string str1, str2, str3;//string()构造函数
    str1 = "Test string: "; //string& operator= (const string & str);
    str2 = 'x';  //string & operator= (const char* s);            
    str3 = str1 + str2;//string& operator= (char c);
    cout << "str1= " << str1 << endl;
    cout << "str2= " << str2 << endl;
    cout << "str3= " << str3 << endl;
    return 0;
}

三.Iterators(迭代器)

1.begin:

Returns an iterator pointing to the first character of the string.

翻译:返回string类对象的第一个字符

实现:

class String
{
public:
    char& begin()
    {
        return _str[0];
    }
private:
    char* _str;
    size_t _size;
    size_t _capacity;
};

2.end:

Returns an iterator pointing to the past-the-end character of the string.
翻译:返回一个迭代器,迭代器指向的string类最后一个字符

The past-the-end character is a theoretical character that would follow the last character in the string. It shall not be dereferenced.
翻译:结束字符是字符串中最后一个字符('\0'),它不应被取消引用

Because the ranges used by functions of the standard library do not include the element pointed by their closing iterator, this function is often used in combination with string::begin to specify a range including all the characters in the string.

翻译:由于标准库的函数所使用的范围不包括其关闭迭代器所指向的元素,因此此函数通常与字符串:begin结合使用,以指定一个包括字符串中所有字符的范围。

If the object is an empty string, this function returns the same as string::begin.

翻译:如果对象是一个空string类,返回也是空

使用实例:

#include <string>
int main()
{
    string s = "hello world";//string& operator= (const string & str);
    string::iterator it = s.begin();
    while (it < s.end())
    {
        cout << *it << " ";
        it++;
    }
    cout << endl;
    return 0;
}

当然迭代器还有很多个,其他的我们后面讲解。

3.rbegin:

Returns a reverse iterator pointing to the last character of the string (i.e., its reverse beginning).
翻译:返回一个反向迭代器指向string类的最后一个字符
Reverse iterators iterate backwards: increasing them moves them towards the beginning of the string.
翻译:反向迭代器向后迭代是指:增加它是指将它向后移动,知道string类对象的起始位置

例子:

#include <string>
int main()
{
    string s1("hello world");
    //注意区别:
    //string::iterator it1 = s1.begin();
    string::reverse_iterator it = s1.rbegin();
    while (it != s1.rend())
    {
        cout << *it;
        it++;//这里++是指向string类的起始位置移动
    }
    cout << endl;
    return 0;
}

所以,大家一定要注意,rbegin和rend++,而不是--

4.rend:

Returns a reverse iterator pointing to the theoretical element preceding the first character of the string (which is considered its reverse end).
翻译:返回一个逆置迭代器指向string类对象首个字符前一个元素
The range between string::rbegin and string::rend contains all the characters of the string (in reverse order).

翻译:rbegin和rend的包含了整个string类对象的字符范围

关于begin、end、rbegin、rend这四个迭代器,我们要注意的就是是否有const修饰

如下:

#include <string>
int main()
{
    string s1("hello world");
    // 可读可写
    string::iterator it2 = s1.begin();
    while (it2 != s1.end())
    {
        *it2 += 3;
        cout << *it2 << " ";
        ++it2;
    }
    cout << endl;
    // 只读
    const string s3("hello world");
    string::const_iterator it3 = s3.begin();
    while (it3 != s3.end())
    {
        // *it3 += 3;//不能修改
        cout << *it3 << " ";
        ++it3;
    }
    cout << endl;
    return 0;
}

注意点:

迭代器写法;

const_iterator /iterator

const_reverse_iterator/reverse_iterator

5.C++11新加的四个:

这四个分别是指用const修饰的begin、end、rbegin、rend这四个迭代器,和之前是有重叠的,大家了解即可。

四.Capacity(容量)

1.size:

Returns the length of the string, in terms of bytes.

翻译:返回string类对象的长度,以字节为单位

This is the number of actual bytes that conform the contents of the string, which is not necessarily equal to its storage capacity.

翻译:这是该string类对象的实际字节数,不一定等于其存储容量。

2.length:

为什么有了size还要有length呢?

其实两者并无差别,原因在于string早于容器出现,最开始时其是用length的,但是后面容器又用了size,所以string也出了个size,但是length肯定不能删除,所以出现了两个作用相同的函数。

3.max_size:

Returns the maximum length the string can reach.
翻译:返回string能到达的最大的长度
This is the maximum potential length the string can reach due to known system or library implementation limitations, but the object is not guaranteed to be able to reach that length: it can still fail to allocate storage at any point before that length is reached.

翻译:这个string类能到达的最大长度会因为系统和库实现限制,但不能保证对象能够达到该长度:在达到该长度之前,它仍然可能无法在任何时候分配存储。

#include <string>
int main()
{
    string s1 = "hello world";
    cout << s1.max_size() << endl;
    return 0;
}

结果:

(x86环境下VS2022)

4.resize

Resizes the string to a length of n characters.
翻译:返回string类n个字符的长度
If n is smaller than the current string length, the current value is shortened to its first n character, removing the characters beyond the nth.
翻译:如果n小于当前string类长度,就会缩减到n个字符,多的会删除
If n is greater than the current string length, the current content is extended by inserting at the end as many characters as needed to reach a size of n. If c is specified, the new elements are initialized as copies of c, otherwise, they are value-initialized characters (null characters).

翻译:如果n大于当前字符串长度,则通过在末尾插入所需数量的字符以达到n的大小来扩展当前内容。如果指定了c,则新元素被初始化为c的副本,否则,它们是值初始化字符(null字符)

例如:

#include <string>
int main()
{
    string s1 = "hello world";
    cout << "curent s1:" << endl;
    cout << s1 << endl;

    cout << "size:" << s1.size() << endl;
    cout << "capacity:" << s1.capacity() << endl;
    //修改size
    string s2 = s1;
    s2.resize(4);
    cout << s2 << endl;
    cout << "当resize<size时:" << endl;
    cout << "size:" << s2.size() << endl;
    cout << "capacity:" << s2.capacity() << endl;
    string s3 = s1;
    s3.resize(14);
    cout << "当resize>size&&resize<capacity时:" << endl;
    cout << s3 << endl;
    cout << "size:" << s3.size() << endl;
    cout << "capacity:" << s3.capacity() << endl;
    string s4 = s1;
    s4.resize(100);
    cout << "当resize>capacity时:" << endl;
    cout << s4 << endl;
    cout << "size:" << s4.size() << endl;
    cout << "capacity:" << s4.capacity() << endl;
    string s5 = s1;
    s5.resize(25,'x');
    cout << "当resize>capacity时:" << endl;
    cout << s5 << endl;
    cout << "size:" << s5.size() << endl;
    cout << "capacity:" << s5.capacity() << endl;
    return 0;
}

结果:

如上,我们就实现过resize两种函数的不同情况下使用情况

5.capacity:

Return size of allocated storage

翻译:返回分配给capacity的空间大小

6.reserve:

Requests that the string capacity be adapted to a planned change in size to a length of up to n characters.
翻译:请求字符串容量适应最大长度为n个字符的计划大小更改。
If n is greater than the current string capacity, the function causes the container to increase its capacity to n characters (or greater).
翻译:如果n大于当前字符串容量,则函数会使容器的容量增加到n个字符(或更大)
In all other cases, it is taken as a non-binding request to shrink the string capacity: the container implementation is free to optimize otherwise and leave the string with a capacity greater than n.
翻译;在所有其他情况下,它被视为收缩字符串容量的非绑定请求:容器实现可以自由地进行其他优化,并使字符串的容量大于n。

This function has no effect on the string length and cannot alter its content.

翻译:此函数对字符串长度没有影响,也不能更改其内容。

我们可以查看扩容机制:

#include <string>
int main()
{
    // 查看扩容机制
    string s;
    s.reserve(10);

    size_t sz = s.capacity();
    cout << "capacity changed: " << sz << '\n';
    cout << "making s grow:\n";
    for (int i = 0; i < 100; ++i)
    {
        s.push_back('c');
        if (sz != s.capacity())
        {
            sz = s.capacity();
            cout << "capacity changed: " << sz << '\n';
        }
    }
    return 0;
}

g++我们以2倍扩容,vs以1.5倍扩容

7.clear:

Erases the contents of the string, which becomes an empty string (with a length of 0 characters).

翻译:删除string类的内容,使string类对象变成一个空类

#include <string>
int main()
{
    string s1 = "hello world";
    cout << s1 << endl;
    s1.clear();
    cout << s1 << endl;
    return 0;
}

结果:

8.empty:

Test if string is empty

翻译:检测string类是否为空

Returns whether the string is empty (i.e. whether its length is 0).
返回string类是否为空(1或0)
This function does not modify the value of the string in any way. To clear the content of a string, see string::clear.

翻译:该函数是不会对string类对象进行任何修改的,如果想将string类清除,请用string::clear

#include <string>
int main()
{
    string s1 = "hello world";
    cout << s1.size() << endl;
    cout << s1.capacity() << endl;
    if (!s1.empty())
    {
        s1.clear();
        cout << s1.size() << endl;
        cout << s1.capacity() << endl;
    }
    return 0;
}

注意点:清空是只改变size,容量是不会清空的!!!

9.shrink_to_fit:

Requests the string to reduce its capacity to fit its size.
翻译:要求将string类对象的容量缩减到与其size相同
The request is non-binding, and the container implementation is free to optimize otherwise and leave the string with a capacity greater than its size.
翻译:这个请求不是盲目的,容器实现会对其进行优化的,否则,留下容量大于string类对象其大小的字符串。
This function has no effect on the string length and cannot alter its content.

翻译:这个函数是不会影响string类对象的长度,同时也不会改变其内容的

#include <string>
int main()
{
    string str(100, 'x');
    cout << "1. capacity of str: " << str.capacity() << '\n';

    str.resize(10);//不改变容量
    cout << "2. capacity of str: " << str.capacity() << '\n';

    str.shrink_to_fit();//容量改变
    cout << "3. capacity of str: " << str.capacity() << '\n';
    return 0;
}

结果:

需要注意的是:改变后的容量不一定就是其size大小

五.Element access(元素访问)

1.string::operator[]:

Returns a reference to the character at position pos in the string.

翻译:返回pos指向的string位置

//通常有以下两种形式:
char& operator[] (size_t pos);//读写形式
const char& operator[] (size_t pos) const;//只读形式

举例:

#include <string>
int main()
{
    string str("hello string");
    for (int i = 0; i < str.size(); ++i)//str.length()
    {
        cout << str[i];
    }
    cout << endl;
    return 0;
}

实现:

#include <string>
class String
{
public:
	char& operator[](size_t pos)
	{
		return _str[pos];
	}

private:
	char* _str;
	size_t _size;
	size_t _capacity;
};

对比:

int a[10]={1,2,3,4,5,6,7,8,9,10};

a[i]和上面str[i]对比:

a[i]:是指*(a+i),本质是指针指向的改变

str[i]:对应的是operator[]运算符重载函数

2.at:

Returns a reference to the character at position pos in the string.
返回string类对象pos位置的字符
The function automatically checks whether pos is the valid position of a character in the string (i.e., whether pos is less than the string length), throwing an out_of_range exception if it is not.

翻译:该函数会自动的检查pos位置是否为string对象的有效位置,如果超出范围,会抛异常

#include <string>
int main()
{
    string s1("hello world");
    cout << s1[4] << endl;
    cout << s1.at(4) << endl;
    return 0;
}

结果:

注意对比:operator[]和at:

operator[]超出范围是不会抛异常的,而at会!!!

3.front和back

back:返回是string对象的最后一个字符

front:返回string对象的首个字符

后面的,我们下一篇再写,bye

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jiaofi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值