zoukankan      html  css  js  c++  java
  • C++解析(18):C++标准库与字符串类

    0.目录

    1.C++标准库

    2.字符串类

    3.数组操作符的重载

    4.小结

    1.C++标准库

    有趣的重载——操作符 << 的原生意义是按位左移,例:1 << 2;,其意义是将整数1按位左移2位,即0000 0001 ——> 0000 0100

    重载左移操作符,将变量或常量左移到一个对象中!

    重载左移操作符:

    #include <stdio.h>
    
    const char endl = '
    ';
    
    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 World!" << endl;
        
        double a = 0.1;
        double b = 0.2;
        
        cout << a + b << endl;
        
        return 0;
    }
    

    运行结果为:

    [root@bogon Desktop]# g++ test.cpp
    [root@bogon Desktop]# ./a.out 
    1
    Hello World!
    0.300000
    

    C++标准库:

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

    C++编译环境的组成:

    C++标准库预定义了多数常用的数据结构:

    使用C++标准库:

    #include <iostream>
    #include <cmath>
    
    using namespace std;
    
    int main()
    {
        cout << "Hello world!" << endl;
        
        double a = 0;
        double b = 0;
        
        cout << "Input a: ";
        cin >> a;
        
        cout << "Input b: ";
        cin >> b;
        
        double c = sqrt(a * a + b * b);
        
        cout << "c = " << c << endl;
        
        return 0;
    }
    

    运行结果为:

    [root@bogon Desktop]# g++ test.cpp
    [root@bogon Desktop]# ./a.out 
    Hello world!
    Input a: 3
    Input b: 4
    c = 5
    

    2.字符串类

    历史遗留问题:

    • C语言不支持真正意义上的字符串
    • C语言用字符数组一组函数实现字符串操作
    • C语言不支持自定义类型,因此无法获得字符串类型

    解决方案:

    • 从C到C++的进化过程引入了自定义类型
    • 在C++中可以通过类完成字符串类型的定义

    C++中的原生类型系统是否包含字符串类型?
    标准库中的字符串类:

    • C++语言直接支持C语言的所有概念
    • C++语言中没有原生的字符串类型

    C++标准库提供了string类型:

    • string直接支持字符串连接
    • string直接支持字符串的大小比较
    • string直接支持子串查找和提取
    • string直接支持字符串的插入和替换

    示例——使用字符串类:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    void string_sort(string a[], int len)
    {
        for(int i=0; i<len; i++)
        {
            for(int j=i; j<len; j++)
            {
                if( a[i] > a[j] )
                {
                    swap(a[i], a[j]);
                }
            }
        }
    }
    
    string string_add(string a[], int len)
    {
        string ret = "";
        
        for(int i=0; i<len; i++)
        {
            ret += a[i] + "; ";
        }
        
        return ret;
    }
    
    int main()
    {
        string sa[6] = 
        {
            "Hello World",
            "C#",
            "Java",
            "C++",
            "Python",
            "TypeScript"
        };
        
        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;
    }
    

    运行结果为:

    [root@bogon Desktop]# g++ test.cpp
    [root@bogon Desktop]# ./a.out 
    C#
    C++
    Hello World
    Java
    Python
    TypeScript
    
    C#; C++; Hello World; Java; Python; TypeScript;
    

    字符串数字的转换——标准库中提供了相关的类对字符串和数字进行转换。
    字符串流类(sstream)用于string的转换:

    • <sstream> —— 相关头文件
    • istringstream —— 字符串输入流
    • ostringstream —— 字符串输出流

    使用方法(string ——> 数字):

    istringstream iss("123.45");
    double num;
    iss >> num;
    

    使用方法(数字 ——> string):

    ostringstream oss;
    oss << 543.21;
    string s = oss.str();
    

    示例——字符串与数字的转换:

    #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("234.567", n) )
        {
            cout << n << endl;    
        }
    
        string s = TO_STRING(12345);
    
        cout << s << endl;     
        
        return 0;
    }
    

    运行结果为:

    [root@bogon Desktop]# g++ test.cpp
    [root@bogon Desktop]# ./a.out 
    234.567
    12345
    

    面试题分析——字符串循环右移
    示例:abcdefg循环右移3位后得到efgabcd

    #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); // s.substr(4) ==> efg
        ret += s.substr(0, pos); // s.substr(0, 4) ==> abcd
        
        return ret;
    }
    
    int main()
    {
        string s = "abcdefg";
        string r = (s >> 3);
        
        cout << r << endl;
        
        return 0;
    }
    

    运行结果为:

    [root@bogon Desktop]# g++ test.cpp
    [root@bogon Desktop]# ./a.out 
    efgabcd
    

    3.数组操作符的重载

    string类对象还具备C方式字符串的灵活性吗?还能直接访问单个字符吗?

    字符串类的兼容性:

    • string最大限度的考虑了C字符串的兼容性
    • 可以按照使用C字符串的方式使用string对象

    示例:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
        string s = "a1b2c3d4e";
        int n = 0;
            
        for(int i = 0; i<s.length(); i++)
        {
            if( isdigit(s[i]) )
            {
                n++;
            }
        }
        
        cout << n << endl;
        
        return 0;
    }
    

    运行结果为:

    [root@bogon Desktop]# g++ test.cpp
    [root@bogon Desktop]# ./a.out 
    4
    

    类的对象怎么支持数组的下标访问?

    重载数组访问操作符:

    • 数组访问符是C/C++中的内置操作符
    • 数组访问符的原生意义是数组访问指针运算

    数组访问操作符([]):

    • 只能通过类的成员函数重载
    • 重载函数能且仅能使用一个参数
    • 可以定义不同参数的多个重载函数

    示例:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Test
    {
        int a[5];
    public:
        int& operator [] (int i)
        {
            return a[i];
        }
        
        int& operator [] (const string& s)
        {
            if( s == "1st" )
            {
                return a[0];
            }
            else if( s == "2nd" )
            {
                return a[1];
            }
            else if( s == "3rd" )
            {
                return a[2];
            }
            else if( s == "4th" )
            {
                return a[3];
            }
            else if( s == "5th" )
            {
                return a[4];
            }
            
            return a[0];
        }
        
        int length()
        {
            return 5;
        }
    };
    
    int main()
    {
        Test t;
        
        for(int i=0; i<t.length(); i++)
        {
            t[i] = i;
        }
        
        for(int i=0; i<t.length(); i++)
        {
            cout << t[i] << endl;
        }
        
        cout << t["5th"] << endl;
        cout << t["4th"] << endl;
        cout << t["3rd"] << endl;
        cout << t["2nd"] << endl;
        cout << t["1st"] << endl;
        
        return 0;
    }
    

    运行结果为:

    [root@bogon Desktop]# g++ test.cpp
    [root@bogon Desktop]# ./a.out 
    0
    1
    2
    3
    4
    4
    3
    2
    1
    0
    

    4.小结

    • C++标准库是由类库函数库组成的集合
    • C++标准库包含经典算法数据结构的实现
    • C++标准库涵盖了C库的功能
    • C++标准库位于std命名空间中
    • 应用开发中大多数的情况都在进行字符串处理
    • C++中没有直接支持原生的字符串类型
    • 标准库中通过string类支持字符串的概念
    • string类支持字符串数字的相互转换
    • string类的应用使得问题的求解变得简单
    • string类最大限度的兼容了C字符串的用法
    • 数组访问符的重载能够使得对象模拟数组的行为
    • 只能通过类的成员函数重载数组访问符
    • 重载函数能且仅能使用一个参数
  • 相关阅读:
    数据库客户端工具Oracle SQL Developer
    Win7系统下搭建FTP
    Apache 中httpd.conf文件配置详解(转载)
    Apache启动报错Address already in use: make_sock: could not bind to...
    QTP如何准确识别Dialog中的对象
    【Apache系列】linux下Apache的常用操作
    【Apache系列】Windows下作为应用程序运行Apache
    【QTP专题】05_参数化之Excel
    CSS伪类before,after制作左右横线中间文字效果
    干货!所有常用的原型设计工具都在这里了
  • 原文地址:https://www.cnblogs.com/PyLearn/p/10085325.html
Copyright © 2011-2022 走看看