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类的应用使得问题的求解变得简单