第33课 C++中的字符串

1. 历史遗留问题及解决方案

(1)历史遗留问题

  ①C语言不支持真正意义上的字符串------c语言是用字符数组实现字符串

  ②C语言用字符数组一组函数模拟字符串操作

  ③C语言不支持自定义类型,因此无法获得字符串类型

(2)解决方案

  ①从C到C++的进化过程引入了自定义类型

  ②在C++中可以通过完成字符串类型的定义

问题:c++中的原生类型系统是否包含字符串类型??? ----------标准库实现

2. 标准库中的字符串类

(1)C++直接支持C语言的所有概念

(2)C++语言中没有原来的字符串类型

(3)C++标准库提供了string类型支持字符串的连接、大小比较、子串查找和提取、字符串的插入和替换等操作

 //字符串排序和连接-----比c语言字符指针实现更简单

 1 #include<iostream>                    //字符串类的使用,使用标准库  避免c中的字符数组,提高开发效率
 2 #include<string>
 3 
 4 using namespace std;
 5 
 6 void string_sort(string a[], int len)       //字符串排序            //排序算法(选择排序两个For循环)
 7 {              
 8     for (int i = 0; i < len; i++)
 9     {
10         for (int j = 0; j < len; j++)
11         {
12             if (a[i] > a[j])           //字符串类string的大小比较,标准库重载了大于小于的操作符
13             {
14                 swap(a[i], a[j]);
15             }
16         }
17     }
18 }
19 
20 string string_add(string a[], int len)        //将参数字符串列表的字符串 连接
21 {
22     string ret = " ";
23 
24     for (int i = 0; i < len; i++)
25     {
26         ret += a[i] + ";";          //标准库有操作符重载+
27     }
28 
29     return ret;
30 }
31 
32 int main()
33 {
34     string sa[7] =
35     {
36             "helloworld",
37             "D.T.Software",
38             "C#",
39             "Java",
40             "Python",
41             "TypeScript"
42     };
43 
44     string_sort(sa, 7);       //基于字典顺序排序
45 
46     for (int i = 0; i < 7; i++)
47     {
48         cout << sa[i] << endl;
49     }  
50 
51     cout << string_add(sa,7) << endl;
52 
53     return 0;
54 }

3. 标准库中的字符串类

(1)字符串流类:(<sstream>头文件)

  • 标准库中提供了相关的类字符串和数字进行转换

  • 字符串流类(sstream)用于string的转换

    • istringstream字符串输入流--------i

    • ostringstream字符串输出流-------o

(2)字符串与数字的转换

  string→数字        

数字→string

istringstream iss("123.45");字符串放入流对象

double num;  变量num接收转化后的值

iss>>num;

ostringstream oss; 定义流对象

oss<<543.21;       数字传到流对象

string s = oss.str();  

 1 #include<iostream>
 2 #include<sstream>               
 3 #include<string>
 4 
 5 //字符串流类sstream完成对字符串和数字的交换     属于类要创建对象使用
 6 //istringstream 字符串输入流
 7 //ostringstream字符串输出流
 8 
 9 using namespace std;
10 
11 int main()
12 {
13 
14     istringstream iss("123.45"); //字符串转数字
15     double num;
16 
17     if (iss >> num)         //  >>右操作数返回值为bool类型
18     {
19         cout << num << endl;           //123.45
20     }
21 
22     ostringstream oss;          //数字转字符串
23     oss << 543.21;         
24     oss << 543 << "." << 21;   //  <<左操作数返回值为oss本身
25 
26     string s = oss.str();
27 
28     cout << s << endl;         //543.21
29 
30 
31     return 0;
32 }
 1 #include<iostream>
 2 #include<sstream>               
 3 #include<string>
 4 
 5 //实际工程做法,定义全局函数to_number 
 6 
 7 using namespace std;
 8 
 9 //整形
10 bool to_number(const string& s, int& n)    //Int型  字符串s转    Int型  n:转换结果
11 {
12     istringstream iss(s);            
13     return iss  >> n;
14 }
15 //浮点型
16 bool to_number(const string& s, double& n)    //Int型  字符串s转  Int型  n
17 {
18     istringstream iss(s);
19     return iss >> n;
20 }
21 
22 //string to_string(int n)
23 {
24     ostringstream oss;
25     oss << s;
26     resturn oss.str();
27 }
28 string to_string(double n)
29 {
30     ostringstream oss;
31     oss << s;
32     resturn oss.str();
33 }
34 
35 //float 型  ?????函数体一致,复制粘贴不太好,能不能用一个函数完成不同数字类型,使用宏
36 
37 
38 int main()
39 {
40     int n = 0;
41     cout << to_number("234", n) << endl;                            
42     cout << n << endl;
43 
44 
45     istringstream iss("123.45"); //字符串转数字
46     double num;
47     if (iss >> num)          //返回值为bool类型
48     {
49         cout << num << endl;           //123.45
50     }
51 
52 
53     ostringstream oss;          //数字转字符串
54     oss << 543.21;              //oss<<543<<"."<<21;   //返回值为左操作数oss对象本身
55     string s = oss.str();
56 
57     cout << s << endl;         //543.21
58 
59 
60     return 0;
61 }
函数体一致,复制粘贴不太好,能不能用一个函数完成不同数字类型,使用宏
 1 #include<iostream>
 2 #include<sstream>               
 3 #include<string>
 4 
 5 //能不能用一个函数完成不同数字类型,,使用宏
 6 
 7 using namespace std;
 8 
 9 #define TO_NUMBER(s,n) (istringstream(s)>>n)     //调用构造函数,产生一个字符串输入流临时对象,宏要在一行代码里完成,临时对象周期满足要求
10 //#define TO_STRING(n)(  (ostringstream()<<n).str() ) //字符串输出流临时对象
11 #define TO_STRING(n)    (((ostringstream&)(ostringstream()<<n)).str())
12 
13 /*string to_string(int n)
14 {
15     ostringstream oss;
16     oss << s;
17     resturn oss.str();
18     //return (ostringstream&(ostringstream() << n)).str();
19 }*/
20 
21 int main()
22 {
23     int n = 0;                   //double n=0;
24 
25     if (TO_NUMBER("234", n))
26     {
27         cout << n << endl;
28     }
29 
30 
31     string s = TO_STRING(12345);
32 
33     cout << s << endl;                                                
34 
35     return 0;
36 }

(3)string类的相关操作

  ①注意事项:

    A. #include <string>。注意,不是<string.h>。

    B. 分为string和wstring版。分别对应char和wchar_t

    C. using std::string;或using std::wstring;

  ②string类的相关操作(https://www.cnblogs.com/5iedu/p/5413930.html

面试题:字符串循环右移
 1 #include<iostream>
 2 #include<string>
 3 
 4 //面试题:完成字符串循环右移3位    abcdefg -->>>efgabcd            使用标准库字符串类
 5 //使用string类成员函数
 6 
 7 using namespace std;
 8 
 9 //string right_func(const string& s, unsigned int n)
10 
11 string operator >> (const string& s, unsigned int n)      //操作符重载右移操作符
12 {
13     string ret = "";
14     unsigned int pos = 0;          // 找子串右移开始的位置;
15 
16     n = n % s.length();            //防止右移位置很大的情况,让其合法;
17     pos = s.length() - n;          //得到最终想要的位置;
18 
19     ret = s.substr(pos);           // 从 pos 开始直到末尾提取子串;
20     ret += s.substr(0, pos);       //原来的字符串并没有被破坏,提取到 pos 之前的字符;
21 
22     return ret;
23 
24     //abcdefg =====>8
25     //abcd efg======>1
26     //8%7========>1           
27 
28     //7-1=======>6
29     //abcded    g
30     //ret==>g
31     //ret===>g+abcdef
32  
33 }
34 
35 int main()
36 {
37 //    string r = right_func("abcdefg", 8);      //函数方式还不太好,可以使用操作符重载
38 
39     string s = "abcdefg";
40     string r = (s>>8);
41 
42     cout << r << endl;
43 
44     return 0;
45 
46 }
47 
48 c语言实现
49 
50 #include <stdio.h>
51 #include <string.h>
52 void right_shift(char* str, char* result, unsigned int n)
53 {
54     int len = strlen(str);
55     for (int i = 0; i < len; i++)
56     {
57         result[(i + n) % len] = str[i];
58     }
59     result[len] = '\0';
60 }
61 
62 int main()
63 {
64     char* str = "abcdefg";
65     char result[255] = { 0 };
66     right_shift(str, result, 3);
67     printf("%s\n", result);
68 
69     return 0;
70 }

面试题:使用 string 类完成--------字符串反转
示例:"we;tonight;you" -- > "ew;thginot;uoy
提示: string 类中提供了成员函数可以查找目标字符的位置

 
 1 #include<iostream>
 2 #include<string>
 3 
 4 //要求:使用 string 类完成
 5 //示例:"we;tonight;you" -- > "ew;thginot;uoy
 6 //提示: string 类中提供了成员函数可以查找目标字符的位置
 7 
 8 using namespace std;
 9 
10 string reverse(const string& s, const char c)
11 {
12     string ret = "";
13     string substr = "";
14 
15     int pos = s.find(c);
16 
17     if (pos != -1)
18     {
19         substr = s.substr(0, pos);
20     }
21     else
22     {
23         substr = s.substr(0);
24     }
25 
26     for (int i = 0; i < substr.length() + 1; i++)
27     {
28         ret += substr[substr.length() - i];  
29     }
30 
31     if (pos != -1)
32     {
33         ret += c;
34         ret += reverse(s.substr(pos + 1), c);
35     }
36 
37     return ret;
38 
39 }
40 
41 int main()
42 {
43     cout << reverse("", ';') << endl;                  // 输出:空字符串
44     cout << reverse(";", ';') << endl;                  // 输出:;
45     cout << reverse("abcde;", ';') << endl;              // 输出:edcba;
46     cout << reverse("we;tonight;you", ';') << endl;   // 输出:ew;thginot;uoy
47 
48 
49     return 0;
50 }

4. 小结

(1)应用开发大多数的情况都在进行字符串处理

(2)C++中没有直接支持原生的字符串类型

(3)标准库中通过string支持字符串的概念

(4)string类支持字符串和数字相互转换

(5)string类应用使得问题的求解变得简单

 

猜你喜欢

转载自www.cnblogs.com/liuyueyue/p/13378644.html