【C++深度解析】21、C++中的字符串类

1 C++ 标准库

1.1 重载左移操作符

我们先来说一下重载左移操作符,下面看一段有趣的代码

// 21-1.cpp
#include<stdio.h>
const char endl = '\n';
class Console
{
public:
    Console& operator << (int i)
    {
        printf("%d", i);
        return *this;
    }
    Console& operator << (char c)
    {
        printf("%c", c);
        return *this;
    }
    Console& operator << (const char* s)
    {
        printf("%s", s);
        return *this;
    }
    Console& operator << (double d)
    {
        printf("%f", d);
        return *this;
    }
};
Console cout;
int main()
{
    cout << 1 <<endl;
    cout << "Hello" <<endl;
    double a = 0.1;
    double b = 0.2;
    cout << a + b << endl;
    return 0;
}

我们定义了一个类 Console,类中重载了左移操作符 <<,定义了一个全局对象 cout,通过宏定义常量 cout,这样可以在不调用 printf 的情况下完成打印功能。

编译运行结果如下:

$ g++ 21-1.cpp -o 21-1
$ ./21-1
1
Hello
0.300000

其实上面这些,C++标准库库中已经给出了实现

1.2 C++标准库

  • C++ 标准库由类库和函数库组成,不是 C++语言的一部分
  • C++标准库中定义的类和对象位于 std 命名空间中,涵盖了 C 库的功能
  • C++ 标准库的头文件没有 .h 后缀

C++ 编译环境包括C++ 的标准语法模块,编译器厂商扩展的语法模块,C++ 的标准库,比如 <string>,C 语言的兼容库,比如 <cstring>,同时 C++ 完全兼容 C 语言。
在这里插入图片描述
C++ 标准库预定于了多数常用的数据结构,如下所示:
在这里插入图片描述

2 C++ 中的字符串类

C 语言不支持真正意义上的字符串,用字符数组和一组函数实现字符串操作。

C++ 没有原生的字符串类型,但是可以自定义类型,通过类完成字符串类型的定义,C++标准库提供了 string 类型,string 支持字符串连接,字符串大小比较,字符串查找与提取,字符串的插入与替换

下面看一下字符串类的使用实验

// 21-2.cpp
#include<iostream>
#include<string>
using namespace std;
void string_sort(string a[], int n)		// 冒泡排序
{
    for (int i = n-1; i >= 0; i--)
    {
        bool flag = false;
        for (int j = 0; j < i; j++)
        {
            if (a[j] > a[j+1])
            {
                swap(a[j], a[j+1]);
                flag = true;
            }
        }
        if (flag == false) break;
    }
}
string string_add(string a[], int n)
{
    string ret = "";
    for (int i = 0; i < n; i++)
    {
        ret += a[i] + "; ";
    }
    return ret;
}
int main()
{
    string sa[6] = {"Hello", "C#", "Java", "C++", "C", "Python"};
    string_sort(sa, 6);
    for (int i = 0; i < 6; i++)
    {
        cout << sa[i] << endl;
    }
    cout << endl;
    cout << string_add(sa, 6) << endl;
    return 0;
}

C++ 中的字符串支持直接用大于号,小于号按照字典序进行大小比较,加号 “+” 可以连接字符串。

编译运行:

$ g++ 21-2.cpp -o 21-2
skx@ubuntu:~/c++$ ./21-2
C
C#
C++
Hello
Java
Python

C; C#; C++; Hello; Java; Python; 

2.1 字符串与数字的转换

字符串流类(sstream)用于对字符串和数字进行转换,头文件为<sstream>

  • istringstream:字符串输入流
  • ostringstream:字符串输出流

在这里插入图片描述
编程实验:字符串和数字的转换

// 21-3.cpp
#include<iostream>
#include<sstream>
#include<string>
using namespace std;

#define TO_NUMBER(s, n) (istringstream(s) >> n)
#define TO_STRING(n) (((ostringstream&)(ostringstream() << n)).str())

int main()
{
    double n  = 0;
    if (TO_NUMBER("123.45", n))
    {
        cout << n << endl;
    }
    string s = TO_STRING(12345);
    cout << s << endl;
    return 0;
}

2.2 字符串循环右移

例如:abcdefg 右移 3 位得到的 efgabcd

//  21-4.cpp
#include<iostream>
#include<string>
using namespace std;
string operator >> (const string& s, unsigned int n)
{
    string ret = "";
    unsigned int pos = 0;
    n = n % s.length();
    pos = s.length() - n; 
    ret = s.substr(pos);
    ret += s.substr(0, pos);
    return ret;
}
int main()
{
    string s = "abcdefg";
    cout << (s >> 3) << endl;
    return 0;
}

s.substr(pos, n)
解释:返回一个string,包含 s 中从 pos 开始的 n 个字符的拷贝(pos 的默认值是0,n 的默认值是 s.size() - pos,即不加参数会默认拷贝整个 s)

3 不要混用C++ 和 C 中的字符串

C++ 中的字符串是类对象,C 中的字符串是字符数组,二者混用会出问题。

// 21-5.cpp
#include<iostream>
#include<string>
using namespace std;
int main()
{
    const char* p = "12345";
    string s = "";
    s.reserve(10);
    for (int i = 0; i < 5; i++)
    {
        s[i] = p[i];
    }
    cout << s << endl;
    return 0;
}

void reserve( size_type size = 0 );
函数reserve()将字符串的容量设置为至少 size。

编译运行:

$ g++ 21-6.cpp -o 21-6
$ ./21-6

我们明明将字符串 p 中的字符拷贝进字符串 s 了,为什么打印出的字符串为空呢?

原因如下:
在这里插入图片描述
虽然字符已经拷贝进字符串 s 中,但是 s 是类的对象,类中的 m_length 一直为 0,所以虽然已经拷贝了字符,编译器依然认为该字符串空,如果两个都是 string 对象,使用赋值运算符直接拷贝就不会出现这样的错误。

4 小结

1、C++ 中没有直接支持原生的字符串类型,通过 string 类支持字符串概念
2、string 类支持字符串和数字的相互转换
3、string 类通过一个成员变量保存字符串长度,通过数据空间保存字符数据,避免 C++ 与 C 字符串混用

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值