C++ string、vector<char>和(const)char *之间的转换

写C++程序时经常会遇到string、vector<char>和(const)char *之间的转换,本文介绍了其间的转换方法和注意事项。

1. string转vector<char>

string所存储字符串不包含'\0',所以转为vector后,通过vector.data()直接输出会有问题,会往后找直到'\0',会出现乱码。所以应该在vector后手动再加上'\0',这样在vector.data()输出字符串就没问题了。但此时vector.size()会比string.length()多1(结束符)。

#include <vector>
#include <iostream>
#include <string>

using namespace std;

int main(void)
{
	string str = "Hello world";
	cout<<"str: length="<<str.length()<<endl;
	cout<<"-----------"<<endl;
	
    //定义vector的同时用string初始化
	vector<char> vec0(str.begin(), str.end());  
	//vec0.emplace_back('\0');
	cout<<"vec0: size="<<vec0.size()<<"  data="<<vec0.data()<<endl;
	cout<<"-----------"<<endl;

    vector<char> vec1;
    /*...*/
    //先定义vector, 再通过assign()利用string初始化	
	vec1.assign(str.begin(), str.end());  
	//vec1.emplace_back('\0');
	cout<<"vec1: size="<<vec1.size()<<"  data="<<vec1.data()<<endl;
	cout<<"-----------"<<endl;
	
	//用string的首地址+length的方式初始化vector
	vector<char> vec2(str.data(), str.data()+str.length());	
	//vec2.emplace_back('\0');
	cout<<"vec2: size="<<vec2.size()<<"  data="<<vec2.data()<<endl;

    //当然上面的方法中都可以使用string的指定部分给vector赋值,比如
    vector<char> vec3{str.begin()+1, str.begin()+5};
    cout<<"vec3: size="<<vec3.size()<<" data=";
    for(auto i:vec3){
        std::cout<<i;
    }
    std::cout<<"\n";
    //当然,如果想通过vec.data输出的话,因为其操作的是char *类型的指针,所以还是需要在vec3的最后添加一个字符串结束符
    vec3.emplace_back('\0');
	cout<<"vec3="<<vec3.data()<<std::endl;
	
    return 0;
}

vector<char>加了'\0'的输出结果:

 

结尾没有加'\0'(代码中注释掉emplace_back('\0'))的输出结果:

 

2. char *转vector<char>

与string转为vector<char>是同样的道理,下面的两种方式vector中都只存储了const char *中的数据部分,没有包含字符串的结束符 '\0',如果不收到在vector的后面加上  '\0',通过vector.data()输出字符串就会有问题,同样意味着vector.size会+1。

#include <vector>
#include <iostream>
#include <string.h>

using namespace std;
int main(void)
{
	const char *buf = "Hello world";
	cout<<"str: length="<<strlen(buf)<<endl;
	cout<<"-----------"<<endl;
	
	//定义vector<char>的同时初始化
	vector<char> vec1(buf, buf+strlen(buf));
	vec1.emplace_back('\0');
	cout<<"vec1: size="<<vec1.size()<<"  data="<<vec1.data()<<endl;
	cout<<"-----------"<<endl;
	
	//先定义vector<char>, 后通过assign()填充数据
	vector<char> vec2;
	vec2.assign(buf, buf+strlen(buf));
	vec2.emplace_back('\0');
	cout<<"vec2: size="<<vec2.size()<<"  data="<<vec2.data()<<endl;
	
    return 0;
}

 vector<char>加了'\0'的输出结果:

结尾没有加'\0'(代码中注释掉emplace_back('\0'))的输出结果:

 3. vector<char>转string

如果vector<char>的最后存入了字符串结束符 '\0',那么用vetor的时候就可以不用指定size,否则就要指定size,不然的话操作string的时候就会出现异常。

#include <vector>
#include <iostream>
#include <string>
#include <string.h>

using namespace std;
int main(void)
{
	const char *buf = "Hello world";
	vector<char> vec1(buf, buf+strlen(buf));
	//vector最后没有存入'\0',但是创建string时指定了size,就不会有问题
	string str1(vec1.data(), vec1.size()); 
	cout<<"str1: size="<<str1.size()<<"  data="<<str1<<endl;
	cout<<"-----------"<<endl;
	
	//如果vector最后存入了'\0',那么用vector初始化string时,可以不指定vector的size
	vector<char> vec2(buf, buf+strlen(buf));
	vec2.emplace_back('\0');
	string str2(vec2.data()); 
	cout<<"str2: size="<<str2.size()<<"  data="<<str2<<endl;
    cout<<"-----------"<<endl;

    //当然也可以使用vector的部分给string 赋值
    vector<char> vec3{'H','e','l','l','o',' ','w','o','r','l','d'};
    string str3{vec3.begin(), vec3.begin()+4};  //string str3(vec3.begin(), vec3.begin()+4); 也是正确的
    cout<<"str3="<<str3<<endl;
    cout<<"\n";

    return 0;
}

上述代码运行结果:

如果vector<char>的最后没有 '\0',也没有指定size(注释掉vec2.emplace_back('\0');),则程序直行结果为:

  4. (const) char *和string互转

(1)可以用char *或const char *直接过string赋值,char *转string时会报warning。

(2)将string转为const char*: 借助string类的c_str()方法,其返回值是const char *类型,所以不能赋值给char *(在c++中const赋值给非const会报错,需借助const_cast强转)。

#include <vector>
#include <iostream>
#include <string>
#include <string.h>

using namespace std;
int main(void)
{
	const char *buf = "Hello world";
	string str = buf;
	cout<<"str:"<<buf<<endl;
	
	string str1("hello");   //string str1{"hello"};  也可以
	const char *buf1;
	buf1 = str1.c_str();
	cout<<"buf1="<<buf1<<endl;
	
	char *buf2;
	buf2 = const_cast<char *>(str1.c_str()); //通过const_cast完成非const到const的转换
	cout<<"buf2="<<buf1<<endl;
    return 0;
}

5.其它说明

5.1在vector和string中使用 {} 和 () 的说明

() 会调用构造函数,{}是列表初始化,也会调用构造函数,在一些场景中使用二者其一都可以,如下:

std::string str{"Hello"};  和  std::string str("Hello");  都ok。

std::vector<char> vec{str.begin(), str.end()}; 和 std::vector<char> vec(str.begin(), str.end());都ok。

std::vector<char> vec1{'H','e','l','l','o'}; ok     std::vector<char> vec2('H','e','l','l','o');  错误

std::string str1(vec1.begin(), vec1.end()); 和 std::string str1{vec1.begin(), vec1.end()}; 都ok。

  • 17
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值