C++字符串操作(string类)

在C++中,处理字符串的类被封装在string类中,其处理较复杂字符串函数操作简于C(cstring为C风格string类头文件,对应类为CString):

//C++风格
str3 = str1 + str2;
//C语言风格
strcpy(str3, str1);
strcat(str3, str2);

以下将对其常用的函数进行举例说明。

1.构造函数

string 类有多个构造函数,用法示例如下:

string s1();  // si = ""
string s2("Hello");  // s2 = "Hello"
string s3(4, 'K');  // s3 = "KKKK"
string s4("12345", 1, 3);  //s4 = "234",即 "12345" 的从下标 1 开始,长度为 3 的子串

注意:string 类没有接收一个整型参数或一个字符型参数的构造函数。下面的两种写法是错误的:

string s1('K');
string s2(123);

2. 对 string 对象赋值

可以用 char* 类型的变量、常量,以及 char 类型的变量、常量对 string 对象进行赋值。例:

 string s1;
s1 = "Hello";  // s1 = "Hello"
s2 = 'K';  // s2 = "K”

(注:以上可以通过赋值运算符“=”进行赋值,这在CString类中是不可以的)
string 类还有 assign 成员函数,可以用来对 string 对象赋值。assign 成员函数返回对象自身的引用。例:

string s1("12345"), s2;
s3.assign(s1);  // s3 = s1
s2.assign(s1, 1, 2);  // s2 = "23",即 s1 的子串(1, 2)
s2.assign(4, 'K');  // s2 = "KKKK"
s2.assign("abcde", 2, 3);  // s2 = "cde",即 "abcde" 的子串(2, 3)

3. 求字符串的长度

length 成员函数返回字符串的长度。size 成员函数可以实现同样的功能。

string str1 = "demo";
int len = str1.size();
cout<<len<<endl;
//输出 4

4. string对象中字符串的连接

除了可以使用+和+=运算符对 string 对象执行字符串的连接操作外,string 类还有 append 成员函数,可以用来向字符串后面添加内容。append 成员函数返回对象自身的引用。例如:

string s1("123"), s2("abc");
s1.append(s2);  // s1 = "123abc"
s1.append(s2, 1, 2);  // s1 = "123abcbc"
s1.append(3, 'K');  // s1 = "123abcbcKKK"
s1.append("ABCDE", 2, 3);  // s1 = "123abcbcKKKCDE",添加 "ABCDE" 的子串(2, 3)

5. string对象的比较

除了可以用 <、<=、==、!=、>=、> 运算符比较 string 对象外,string 类还有 compare 成员函数,可用于比较字符串。compare 成员函数有以下返回值:
小于 0 表示当前的字符串小;
等于 0 表示两个字符串相等;
大于 0 表示另一个字符串小。

// "aBcd" 和 "Abcd"比较------ a > A

cout << "A.compare(B):" << A.compare(B)<< endl;                          // 结果:1
// "cd" 和 "Abcd"比较------- c > A
cout << "A.compare(2, 3, B):" <<A.compare(2, 3, B)<< endl;                // 结果:1

// "cd" 和 "cd"比较 
cout << "A.compare(2, 3, B, 2, 3):" << A.compare(2, 3, B, 2, 3) << endl;  // 结果:0

// 由结果看出来:0表示下标,3表示长度
// "123" 和 "123"比较 
cout << "C.compare(0, 3, D, 0, 3)" <<C.compare(0, 3, D, 0, 3) << endl;    // 结果:0

6. 求 string 对象的子串

substr 成员函数可以用于求子串 (n, m),原型如下:

string substr(int n = 0, int m = string::npos) const

调用时,如果省略 m 或 m 超过了字符串的长度,则求出来的子串就是从下标 n 开始一直到字符串结束的部分。例如:

string s1 = "this is ok";
string s2 = s1.substr(2, 4);  // s2 = "is i"
s2 = s1.substr(2);  // s2 = "is is ok"

7. 交换两个string对象的内容

swap 成员函数可以交换两个 string 对象的内容。例如:

string s1("West”), s2("East");
s1.swap(s2);  // s1 = "East",s2 = "West"

8. 查找子串和字符

string 类有一些查找子串和字符的成员函数,它们的返回值都是子串或字符在 string 对象字符串中的位置(即下标)。如果查不到,则返回 string::npos。string: :npos 是在 string 类中定义的一个静态常量。这些函数如下:
find:从前往后查找子串或字符出现的位置。
rfind:从后往前查找子串或字符出现的位置。
find_first_of:从前往后查找何处出现另一个字符串中包含的字符。例如:
s1.find_first_of(“abc”); //查找s1中第一次出现"abc"中任一字符的位置
find_last_of:从后往前查找何处出现另一个字符串中包含的字符。
find_first_not_of:从前往后查找何处出现另一个字符串中没有包含的字符。
find_last_not_of:从后往前查找何处出现另一个字符串中没有包含的字符。
下面是 string 类的查找成员函数的示例程序。

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string s1("Source Code");
    int n;
    if ((n = s1.find('u')) != string::npos) //查找 u 出现的位置
        cout << "1) " << n << "," << s1.substr(n) << endl;
    //输出 l)2,urce Code
    if ((n = s1.find("Source", 3)) == string::npos)
        //从下标3开始查找"Source",找不到
        cout << "2) " << "Not Found" << endl;  //输出 2) Not Found
    if ((n = s1.find("Co")) != string::npos)
        //查找子串"Co"。能找到,返回"Co"的位置
        cout << "3) " << n << ", " << s1.substr(n) << endl;
    //输出 3) 7, Code
    if ((n = s1.find_first_of("ceo")) != string::npos)
        //查找第一次出现或 'c'、'e'或'o'的位置
        cout << "4) " << n << ", " << s1.substr(n) << endl;
    //输出 4) l, ource Code
    if ((n = s1.find_last_of('e')) != string::npos)
        //查找最后一个 'e' 的位置
        cout << "5) " << n << ", " << s1.substr(n) << endl;  //输出 5) 10, e
    if ((n = s1.find_first_not_of("eou", 1)) != string::npos)
        //从下标1开始查找第一次出现非 'e'、'o' 或 'u' 字符的位置
        cout << "6) " << n << ", " << s1.substr(n) << endl;
    //输出 6) 3, rce Code
    return 0;
}

9. 替换子串

replace 成员函数可以对 string 对象中的子串进行替换,返回值为对象自身的引用。例如:

string s1("Real Steel");
s1.replace(1, 3, "123456", 2, 4);  //用 "123456" 的子串(2,4) 替换 s1 的子串(1,3)
cout << s1 << endl;  //输出 R3456 Steel
string s2("Harry Potter");
s2.replace(2, 3, 5, '0');  //用 5 个 '0' 替换子串(2,3)
cout << s2 << endl;  //输出 HaOOOOO Potter
int n = s2.find("OOOOO");  //查找子串 "00000" 的位置,n=2
s2.replace(n, 5, "XXX");  //将子串(n,5)替换为"XXX"
cout << s2 < < endl;  //输出 HaXXX Potter

10. 删除子串

erase 成员函数可以删除 string 对象中的子串,返回值为对象自身的引用。例如:

string s1("Real Steel");
s1.erase(1, 3);  //删除子串(1, 3),此后 s1 = "R Steel"
s1.erase(5);  //删除下标5及其后面的所有字符,此后 s1 = "R Ste"

11. 插入字符串

insert 成员函数可以在 string 对象中插入另一个字符串,返回值为对象自身的引用。例如:

string s1("Limitless"), s2("00");
s1.insert(2, "123");  //在下标 2 处插入字符串"123",s1 = "Li123mitless"
s1.insert(3, s2);  //在下标 2 处插入 s2 , s1 = "Li10023mitless"
s1.insert(3, 5, 'X');  //在下标 3 处插入 5 个 'X',s1 = "Li1XXXXX0023mitless"

12. 用 STL 算法操作 string 对象

string 对象也可以看作一个顺序容器,它支持随机访问迭代器,也有 begin 和 end 等成员函数。STL 中的许多算法也适用于 string 对象。下面是用 STL 算法操作 string 对象的程序示例。

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
    string s("afgcbed");
    string::iterator p = find(s.begin(), s.end(), 'c');
    if (p!= s.end())
        cout << p - s.begin() << endl;  //输出 3
    sort(s.begin(), s.end());
    cout << s << endl;  //输出 abcdefg
    next_permutation(s.begin(), s.end());
    cout << s << endl; //输出 abcdegf
    return 0;
}

13. 字符串和十进制相互转换

(1)十进制转字符串

int a = 345;
string str = to_string(a);
cout <<str << endl

(2)字符串转十进制

string str =3456;
int a = stoi(str);
cout << a << endl

14. 一个例子——计算某字符出现次数

#include <string>
#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
    string str1 = "8 8 8  8A i i OOI              IIIaa";
    char dst = 'A';
    getline(cin, str1);
    cin >> dst;
    int len1 = str1.size();
    //cout<<str1<<endl;
    int count = 0;
    if (len1 > 0 && len1 < 100000) {
        int pos = 0;
        for (int i = 0; i < len1; i++) 
            int asc = 0;
            if (dst < 65 && dst > 32) {
                if (str1[i] == dst
                    count++;
            }
            //cout<<dst;
            if (dst > 64) {
                asc = dst + 32;
                if (dst > 96)
                    asc = dst - 32;
                if (str1[i] == dst || str1[i] == asc)
                    count++;
            }
        }
    }
    cout << count << endl;
    return 0;
}

15. 处理char*字符串

1)字符串操作

strcpy(p, p1) 复制字符串 
strncpy(p, p1, n) 复制指定长度字符串 
strcat(p, p1) 附加字符串 
strncat(p, p1, n) 附加指定长度字符串 
strlen(p) 取字符串长度 
strcmp(p, p1) 比较字符串 
strcasecmp忽略大小写比较字符串
strncmp(p, p1, n) 比较指定长度字符串 
strchr(p, c) 在字符串中查找指定字符 
strrchr(p, c) 在字符串中反向查找 
strstr(p, p1) 查找字符串 
strpbrk(p, p1) 以目标字符串的所有字符作为集合,在当前字符串查找该集合的任一元素 
strspn(p, p1) 以目标字符串的所有字符作为集合,在当前字符串查找不属于该集合的任一元素的偏移 
strcspn(p, p1) 以目标字符串的所有字符作为集合,在当前字符串查找属于该集合的任一元素的偏移  
具有指定长度的字符串处理函数在已处理的字符串之后填补零结尾符 

2)字符串到数值类型的转换

strtod(p, ppend) 从字符串 p 中转换 double 类型数值,并将后续的字符串指针存储到 ppend 指向的 char* 类型存储。
strtol(p, ppend, base) 从字符串 p 中转换 long 类型整型数值,base 显式设置转换的整型进制,设置为 0 以根据特定格式判断所用进制,0x, 0X 前缀以解释为十六进制格式整型,0    前缀以解释为八进制格式整型
atoi(p) 字符串转换到 int 整型 
atof(p) 字符串转换到 double 符点数 
atol(p) 字符串转换到 long 整型 

3)字符检查

isalpha() 检查是否为字母字符 
isupper() 检查是否为大写字母字符 
islower() 检查是否为小写字母字符 
isdigit() 检查是否为数字 
isxdigit() 检查是否为十六进制数字表示的有效字符 
isspace() 检查是否为空格类型字符 
iscntrl() 检查是否为控制字符 
ispunct() 检查是否为标点符号 
isalnum() 检查是否为字母和数字 
isprint() 检查是否是可打印字符 
isgraph() 检查是否是图形字符,等效于 isalnum() | ispunct() 

16. 一个例子:重命名文件名

string resetName(string filename)
{
	//C++
	int pos = filename.find(".");
	//filename.assign("test.txt");
	string roiFilename = filename.substr(0, pos);
	roiFilename += ".raw_rect.txt";

	//C
	char ch[_MAX_PATH];
	strcpy(ch, filename.c_str());
	cout << strlen(ch) << endl;

	int n = strlen(ch);
	char p[_MAX_PATH] = "";
	char p1[20] = "_rect.txt";
	strncpy(p, ch, n - 8); //复制指定长度字符串
	strcat(p, p1); //附加字符串
	return roiFilename;
}

参考文献
[1] http://c.biancheng.net/view/400.html
[2] https://blog.csdn.net/s876286443/article/details/22984485

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值