不要随意混用string和C风格字符串

       最近在参与一个前人做了一半的项目,可能是由于之前开发人员并不固定,大家的编码风格不同,本来是个C++的项目,里面却出现了C和C++风格混乱的代码。这里并不是说C和C++熟优熟劣,而是觉得实际项目中应该选定一种编码风格,如果是用C,那就坚持用C,如果选择了C++,那就坚持C++的封装原则。不应该一会C++的风格,一会又是C的风格。

       也许大家会说C++本来就是兼容C的,有什么不可呢?我的看法是:对于资深的C++程序员,他们十分清楚C和C++的不同,在混合使用C和C++时已经十分清楚需要留意以防出错的地方,混用C/C++也许能写出既具备C的高效,有又C++的封装优势的代码来。但对于像我这样的菜鸟,在同一个项目中还是应该坚持一种风格的代码。

       下面先说说C++string类的几个不易区分的函数,然后再结合项目中遇到的问题来说明为什么要坚持一种风格的代码。

       c_str()和data()的区别是:c_str()返回以‘\0’(ascall码为0)结尾的C风格字符串,而data()返回的字符串结尾没有'\0'。需要注意的是,c_str()的返回结果有时候并不是完整的string对象的内容,原因是string对象本身可能包含一个或多个'\0',c_str()返回一个const char*类型的指针,当我们用这个指针来操作C风格的字符串的时候,就会出现阶段,因为C风格的字符串是以'\0'作为结束符的。见下面的例子:

#include <iostream>
#include <string>

using namespace std;

int main() {
	
	string str1("abc");
	cout << str1.size() << endl;
	cout << str1.c_str() << endl;

	string str2("\0\0\0");
	cout << str2.size() << endl;
	cout << str2.c_str() << endl;

	string str3("a\0c");
	cout << str3.size() << endl;
	cout << str3.c_str() << endl;

	string str4("a\0c", 5);
	cout << str4.size() << endl;
	cout << str4.c_str() << endl;

	string str5(5, '\0');
	cout << str5.size() << endl;
	cout << str5.c_str() << endl;

	system("pause");

	return 0;
}
运行结果如下:


注意上面代码中不同构造函数的区别,str1,str2,str3用的是构造函数string::string(const char *),这种构造函数的内部,可能会在开始的时候,为string内部的char*申请空间,将参数指向的C风格字符串拷贝到申请的空间上,这个时候已经发生了截断,所以构造得到的string不包含'\0'(具体实现有待进行源码考证)。


所以,如非必要(例如调用一些外部提供的接口函数,而函数的参数是const char*),最好不要用c_str()将string转化为const char *,毕竟string类本身已经封装了各种操作,为什么不去使用呢?

size和length的效果一样,都是返回string的长度,但size更符合STL容器的风格。需要注意的是,string类里面封装了一个char*指针,但string的长度绝不依赖于以‘\0’作为结束符,也就是说size和length函数在计算string对象的长度时并不是以‘\0’为结束符来判断的,而是在构造一个string对象时计算好的(当然,后期对string的追加和删减操作会相应修改string的长度)。

最后再说说我在项目中遇到的问题,项目从外部读入各种编码格式的html文本文件,放在string(或wstring)里面,由于有些的编码格式会在字符串中安插‘\0’,如果将string转化为const char *就会出现截断,导致不能处理完整的文本。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值