C++中string、char、char*、const char、const char*详解及相关函数及相互转换

博客主要介绍了C++中string与const char*、char*之间的相互转换,包括转换方法及VS2017中的报错解决办法。还阐述了string类相关操作,如声明、大小和容量、字符串比较、插入、拼接、遍历、删除、替换、查找、分割截取和排序等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、各个之间相互的转换

1.string转const char*

string s ="abc";
const char* c_s = s.c_str();

 2.const char*转string

//直接赋值即可
const char* c_s ="abc";
string s(c_s);

3.string转char*

//方法一
string s ="abc";
char* c;
const int len = s.length();
c =new char[len+1];
strcpy(c,s.c_str());

//方法二
string s ="abc";
char* c = new char[s .size()];
strcpy(c, s.data());

4.char*转string

//直接赋值即可
char* c ="abc";
string s(c);

注意:

在VS2017中  char* c ="abc";  这句会报错——const char*类型的值不能用于初始化char*类型的实体

解决办法:在项目属性中C/C++——语言——符合模式默认为是,将其改为否则编译不再报错

                  或者写成:char a[] = "abc";  char* c = a;

原因:"abc"是常量,正确的写法本身就是:const char* c = "abc";  之所以写成char*是历史遗留原因,但你修改这个字符串时,你的程序可能就崩溃了,新版本VS对这个进行了更严格的控件。

5.const char*转char*

const char* cpc ="abc";
char* pc =new char[100];//足够长
strcpy(pc,cpc);

二、string类相关

 1.声明一个C++字符串

string str;

这样我们就声明了一个字符串变量,但既然是一个类,就有构造函数和析构函数。上面的声明没有传入参数,所以就直接使用了string的默认的构造函数,这个函数所做的就是把str初始化为一个空字符串。

注意:C++不要把对象作为返回值,特别是string,CString,这些类型。跨模块的时候相当危险。

string类的构造函数和析构函数如下:

string s;  //生成一个空字符串s
string s(str) //拷贝构造函数 生成str的复制品
string s(str,stridx) //将字符串str内“始于位置stridx”的部分当作字符串的初值
string s(str,stridx,strlen) //将字符串str内“始于stridx且长度顶多strlen”的部分作为字符串的初值
string s(cstr) //将C字符串作为s的初值
string s(chars,chars_len) //将C字符串前chars_len个字符作为字符串s的初值。
string s(num,c) //生成一个字符串,包含num个c字符
string s(beg,end) //以区间beg;end(不包含end)内的字符作为字符串s的初值
s.~string() //销毁所有字符,释放内存

2.string的大小和容量

/*
1. size()和length():返回string对象的字符个数,他们执行效果相同。
2. max_size():返回string对象最多包含的字符数,超出会抛出length_error异常
3. capacity():重新分配内存之前,string对象能包含的最大字符数
*/
void test()
{
    string s("1234567");
    cout << "size=" << s.size() << endl;          //7
    cout << "length=" << s.length() << endl;      //7
    cout << "max_size=" << s.max_size() << endl;  //4294967294
    cout << "capacity=" << s.capacity() << endl;  //15
}

3.string的字符串比较

1. C ++字符串支持常见的比较操作符(>,>=,<,<=,==,!=)   

2. 另一个功能强大的比较函数是成员函数compare()。他支持多参数处理,支持用索引值和长度定位子串来进行比较。他返回一个整数来表示比较结果,返回值意义如下:

0:相等       1:大于       -1:小于  

void test()
{
    // (A的ASCII码是65,a的ASCII码是97)
    // 前面减去后面的ASCII码,>0返回1,<0返回-1,相同返回0
    string A("aBcd");
    string B("Abcd");
    string C("123456");
    string D("123dfg");
    // "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
}

4.string的插入:push_back()和insert()

void  test()
{
    string s1;

    // 在尾部插一个字符
    s1.push_back('a');
    s1.push_back('b');
    s1.push_back('c');
    cout<<"s1:"<<s1<<endl; // s1:abc

    // insert(pos,char):在指定的位置pos前插入字符char
    s1.insert(s1.begin(),'1');
    cout<<"s1:"<<s1<<endl; // s1:1abc
}

5.拼接字符串:append() & + 操作符

void test5()
{
    // 方法一:append()
    string s1("abc");
    s1.append("def");
    cout<<"s1:"<<s1<<endl; // s1:abcdef

    // 方法二:+ 操作符
    string s2 = "abc";
    /*s2 += "def";*/
    string s3 = "def";
    s2 += s3.c_str();
    cout<<"s2:"<<s2<<endl; // s2:abcdef
}

6.string的遍历:借助迭代器或者下标法

void test6()
{
    string s1("abcdef"); // 调用一次构造函数

    // 方法一: 下标法
    for( int i = 0; i < s1.size() ; i++ )
    {
        cout<<s1[i];
    }
    cout<<endl;                                        //abcdef

    // 方法二:正向迭代器
    string::iterator iter = s1.begin();
    for( ; iter < s1.end() ; iter++)
    {
        cout<<*iter;
    }
    cout<<endl;                                        //abcdef

    // 方法三:反向迭代器
    string::reverse_iterator riter = s1.rbegin();
    for( ; riter < s1.rend() ; riter++)
    {
        cout<<*riter;
    }
    cout<<endl;                                        //fedcba
}

7.string的删除:erase()

iterator erase(iterator p);//删除字符串中p所指的字符
iterator erase(iterator first, iterator last);//删除字符串中迭代器区间[first,last)上所有字符
string& erase(size_t pos = 0, size_t len = npos);//删除字符串中从索引位置pos开始的len个字符
void clear();//删除字符串中所有字符

void test()
{
    string s1 = "123456789";

    // s1.erase(s1.begin()+1);              // 结果:13456789
    // s1.erase(s1.begin()+1,s1.end()-2);   // 结果:189
    s1.erase(1,6);                       // 结果:189
    string::iterator iter = s1.begin();
    while( iter != s1.end() )
    {
        cout<<*iter;
        *iter++;
    }
    cout<<endl;
}

8.string的字符替换

string& replace(size_t pos, size_t n, const char *s);//将当前字符串从pos索引开始的n个字符,替换成字符串s
string& replace(size_t pos, size_t n, size_t n1, char c); //将当前字符串从pos索引开始的n个字符,替换成n1个字符c
string& replace(iterator i1, iterator i2, const char* s);//将当前字符串[i1,i2)区间中的字符串替换为字符串s

void test()
{
    string s1("hello,world!");

    cout<<s1.size()<<endl;                     // 结果:12
    s1.replace(s1.size()-1,1,1,'.');           // 结果:hello,world.

    // 这里的6表示下标  5表示长度
    s1.replace(6,5,"girl");                    // 结果:hello,girl.
    // s1.begin(),s1.begin()+5 是左闭右开区间
    s1.replace(s1.begin(),s1.begin()+5,"boy"); // 结果:boy,girl.
    cout<<s1<<endl;
}

9.string的查找:find()

//在当前字符串的pos索引位置开始,查找子串s,返回找到的位置索引,-1表示查找不到子串
size_t find (constchar* s, size_t pos = 0) const;
//在当前字符串的pos索引位置开始,查找字符c,返回找到的位置索引,-1表示查找不到字符
size_t find (charc, size_t pos = 0) const;
//在当前字符串的pos索引位置开始,反向查找子串s,返回找到的位置索引,-1表示查找不到子串
size_t rfind (constchar* s, size_t pos = npos) const;
//在当前字符串的pos索引位置开始,反向查找字符c,返回找到的位置索引,-1表示查找不到字符
size_t rfind (charc, size_t pos = npos) const;
//在当前字符串的pos索引位置开始,查找子串s的字符,返回找到的位置索引,-1表示查找不到字符
size_tfind_first_of (const char* s, size_t pos = 0) const;
//在当前字符串的pos索引位置开始,查找第一个不位于子串s的字符,返回找到的位置索引,-1表示查找不到字符
size_tfind_first_not_of (const char* s, size_t pos = 0) const;
//在当前字符串的pos索引位置开始,查找最后一个位于子串s的字符,返回找到的位置索引,-1表示查找不到字符
size_t find_last_of(const char* s, size_t pos = npos) const;
//在当前字符串的pos索引位置开始,查找最后一个不位于子串s的字符,返回找到的位置索引,-1表示查找不到子串
size_tfind_last_not_of (const char* s, size_t pos = npos) const;

void test()
{
    string s("dog bird chicken bird cat");

    //字符串查找-----找到后返回首字母在字符串中的下标

    // 1. 查找一个字符串
    cout << s.find("chicken") << endl;        // 结果是:9

    // 2. 从下标为6开始找字符'i',返回找到的第一个i的下标
    cout << s.find('i',6) << endl;            // 结果是:11

    // 3. 从字符串的末尾开始查找字符串,返回的还是首字母在字符串中的下标
    cout << s.rfind("chicken") << endl;       // 结果是:9

    // 4. 从字符串的末尾开始查找字符
    cout << s.rfind('i') << endl;             // 结果是:18-------因为是从末尾开始查找,所以返回第一次找到的字符

    // 5. 在该字符串中查找第一个属于字符串s的字符
    cout << s.find_first_of("13br98") << endl;  // 结果是:4---b

    // 6. 在该字符串中查找第一个不属于字符串s的字符------先匹配dog,然后bird匹配不到,所以打印4
    cout << s.find_first_not_of("hello dog 2006") << endl; // 结果是:4
    cout << s.find_first_not_of("dog bird 2006") << endl;  // 结果是:9

    // 7. 在该字符串最后中查找第一个属于字符串s的字符
    cout << s.find_last_of("13r98") << endl;               // 结果是:19

    // 8. 在该字符串最后中查找第一个不属于字符串s的字符------先匹配t--a---c,然后空格匹配不到,所以打印21
    cout << s.find_last_not_of("teac") << endl;            // 结果是:21
}

10.string的分割/截取字符串:strtok() & substr()

//分割
void test()
{
    char str[] = "I,am,a,student; hello world!";

    const char *split = ",; !";
    char *p2 = strtok(str,split);
    while( p2 != NULL )
    {
        cout<<p2<<endl;
        p2 = strtok(NULL,split);
    }
}
//输出:
//I
//am
//a
//student
//hello
//world

//截取
void test()
{
    string s1("0123456789");
    string s2 = s1.substr(2,5); // 结果:23456-----参数5表示:截取的字符串的长度
    cout<<s2<<endl;
}

11.string的排序:sort(s.begin(),s.end())

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

void test9()
{
    string s = "cdefba";
    sort(s.begin(),s.end());
    cout<<"s:"<<s<<endl;     // 结果:abcdef
}

转载自:https://www.cnblogs.com/wuyepeng/p/9729943.html

https://blog.youkuaiyun.com/qq_37941471/article/details/82107077

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值