Keep on going, never give up.

string类c_str、data与\0使用

以前一直使用string::data()函数没发现什么问题,前天居然发现string::data不能用了,也就是data()返回没有结束符,导致拷贝崩溃,后来一查,这个data函数返回是不一定会包含结束符的。写本文专门写了个测试程序去复现,测试程序却又带\0结束符返回,编译器什么都没换过(指教)。

不过不管怎样,还是使用c_str()保险,对涉及中间带\0的string,使用data()时,注意结合len来进行安全限定。

一、string::data不带结束符、string::c_str带结束符

这是:

http://www.cplusplus.com/reference/string/string/data/

http://www.cplusplus.com/reference/string/string/c_str/

说法,而天缘实际测试,这个data函数还是有\0添加返回的。测试程序如下:

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

bool fun(string x) {
	const char* p=x.data();
	return true;
}

void main() {

	string	s1 = "98765432109876543210A";
	char*	s2 = "12345";
	char	s3[] = "12345";
	char res[255];

	int len1 = s1.length();	//=21, no(or not including) '\0'(terminating null character)
	int len2 = strlen(s2);	//=5, no(or not including) '\0'
	int len3 = strlen(s3);	//=5, no(or not including) '\0'

	const char* abuf = s1.c_str();	//append '\0'
	strcpy(res,abuf);				//ok, find '\0'

	const char* bbuf = s1.data();	//find '\0' (maybe no)
	strcpy(res,s1.data());			//Do not use this

	string s4 = "12345 \0 54321";	//s4="12345 "
	size_t len=s4.length();			//=6
	size_t size=s4.size();			//=6
	const char*ps=s4.c_str();

	string s5= string("12345 \0 54321", 13);//s5=12345 \0 54321
	//const char*pd=s5.data();
	fun(s5);
}

但确实也遇到过没有结束符返回的情况,好像内容很长时(函数引用?...),当时就因为没有结束符导致拷贝崩溃。后来全部换成c_str()了。

二、勿通过string::data、string::c_str返回指针修改string内容

也就是说data()和c_str()只供引用使用。而且一旦string内容变动,则必须重新获取该指针。string对象的赋值,必须使用符合string类规则的处理方式,比如构造、append、erase等函数进行。

具体参考:http://www.cplusplus.com/reference/string/string/

三、中间带\0结束符的string对象

有多种方法可实现中间带结束符\0的string对象初始化。但是像:

string s="123 \0 123";
s5="abc\0";
s5+="def\0";

这样的初始化方法都是不行的,因为编译器或运行时默认都会截掉结束符后面的字符串。结果就是:

s="123 "

s5="abcdef"

1、构造法初始化

string s5= string("12345 \0 54321", 13);

这样的方式初始化,这时 s5="12345 \0 54321"

2、append函数添加

除了上面方法,还可以使用append函数,代码如下:

	s5.append("abc\0",4);
	s5.append("def\0",4);

相关评论(0):  

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

订阅博客

最新文章

本站采用创作共用版权协议, 要求署名、非商业用途和保持一致. 转载也必须遵循“署名-非商业用途-保持一致”的创作共用协议. 返回顶部
Copyright@2005-2016 Metsky.com, All rights Reserved.