33_C++ 中的字符串类

0. 历史遗留问题

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

1. 解决方案

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

2. 标准库中的字符串类

  • 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;
}

void print(string a[], int len)
{
    for(int i=0; i<len; i++)
    {
        cout << a[i] << endl;
    }
}

int main()
{
    string sa[7] = 
    {
        "Hello World", 
        "D.T.Software",
        "C#",
        "Java",
        "C++",
        "Python",
        "TypeScript"
    };
    
    string_sort(sa, 7);

    print(sa, 7);
    
    cout << endl;
    
    cout << string_add(sa, 7) << endl;  
    
    return 0;
}

输出结果:

C#
C++
D.T.Software
Hello World
Java
Python
TypeScript

C#; C++; D.T.Software; Hello World; Java; Python; TypeScript; 

3. 标准库中的字符串类——字符串与数字的转换:字符串流类(sstream)

  • 字符串与数字的转换
    • 标准库中提供了相关的类对字符串和数字进行转换
    • 字符串流类(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>

// 使用宏来转换,用到了临时对象
#define TONUMBER(s, n) (istringstream(s)>>n)    
#define TOSTRING(n) (((ostringstream&)(ostringstream() << n)).str())

using namespace std;

/*
bool to_number(const string& s, int& n) // 使用全局函数来将字符串转化为数字(数字类型只能固定,需要用到后面的模板)
{
    istringstream iss(s);
    return iss >> n;
}
*/

/*
string to_string(int n)     // 使用全局函数来将数字转化为字符串(数字类型只能固定,需要用到后面的模板)     
{
    string s = "";
    
    ostringstream oss;
    oss << n;
    
    s = oss.str();
    
    return s;
}
*/

int main()
{
    int num = 0;
    
    if(TONUMBER("123", num))
    {
        cout << num << endl;
    }
    
    cout << TOSTRING(789) << endl;

    return 0;
}

输出结果:

123
789

4. 面试题分析:字符串循环右移

编程说明:字符串循环右移

#include <iostream>
#include <string>

using namespace std;

string operator >> (const string& s, unsigned int n)
{
    string ret = "";
    
    // abcdefd ==> 3 ==> efgabcd

    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 str = "abcdefg";

    cout << (str >> 3) << endl;

    return 0;
}

输出结果:

efgabcd

5. 小结

  • 应用开发中大多数的情况都是在进行字符串处理
  • C++中没有直接支持原生的字符串类型
  • 标准库中string类支持字符串的概念
  • string类支持字符串数字的相互转换
  • string类的应用使得问题的求解变得简单

6. 课后练习

字符串反转

自己测试通过的代码,希望有朋友看到后提出不同的测试代码,一起讨论。测试过程中,由于作业要求必须传入const string& s,只读字符串的转换困扰我许久,后来通过强制转换后实现并测试通过

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

string str_reverse(const string& s, const char c)
{
    string ret = "";
    string* ss = const_cast<string*> (&s);
    int n = (*ss).find(c);

    while( n != string::npos)
    {
        string sub_str = "";
        int pos = 0;

        sub_str = (*ss).substr(pos, n);
        reverse(sub_str.begin(), sub_str.end());
        ret += sub_str + c; 
        (*ss) = (*ss).substr(n+1);
        n = (*ss).find(c);
    }

    reverse((*ss).begin(), (*ss).end());    
    ret += (*ss);
    
    return ret;
}


int main()
{
    cout << str_reverse("", ';') << endl;                 // 输出:空字符串
    cout << str_reverse(";", ';') << endl;                // 输出:;
    cout << str_reverse("abcde;", ';') << endl;           // 输出:edcba;
    cout << str_reverse("we;tonight;you", ';') << endl;   // 输出:ew;thginot;uoy


    return 0;
}

输出结果:


;
edcba;
ew;thginot;uoy
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,602评论 18 399
  • 一、字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 s...
    JaiUnChat阅读 1,655评论 0 7
  • 1)字符串操作strcpy(p, p1) 复制字符串strncpy(p, p1, n) 复制指定长度字符串strc...
    XDgbh阅读 4,398评论 0 10
  • 前面的课程,叶武滨老师都是分享的方法的问题,包括反思、列计划、怎么管理事物等。此次课叶老师和我们分享了方向层面的问...
    皓月环宇阅读 598评论 0 0