(18)C风格字符串与旧代码的接口

来源:互联网 发布:更改网卡mac地址win10 编辑:程序博客网 时间:2024/05/16 15:09
字符串字面值是一种通用结构的实例,这种结构即是C++由C继承而来的C风格字符串。C风格字符串不是一种类型,而是为了表达和使用字符串而形成的一种约定俗成的写法。按此习惯书写的字符串存放在字符数组中并以空字符结束。一般利用指针来操作这些字符串。

C语言标准库提供的一组函数,这些函数可用于操作C风格字符串,它们定义在cstring头文件中,cstring是C语言头文件string.的C++版本。


上面所列的函数并不验证其字符串参数。

传入此类函数的指针必须指向以空字符作为结束的数组:

char  ca[]={'c','+','+'};//不以空字符结束cout<<strlen(ca)<<endl;//错误,ca没有以空字符结束</span>
上述程序将产生未定的结果,或者strlen函数将可能沿着ca在内存中的位置不断向前寻找,直到遇到空字符才停止。


比较字符串:
比较两个C风格字符串的方法和之前学习过的比较标准库string对象的方法大相径庭。比较标准库string对象的时候,用的是普通的关系运算符和相等性运算符。

string s1="helloworld";string s2="C++";if(s1<s12)//false s1>s2</span>
如果把这些运算用在两个C风格字符串上,实际上比较的是指针而非字符串本身,产生的结果是未定义的。要想比较两个C风格字符串需要调用strcmp函数,此时比较的就不再是指针了。


连接和拷贝C风格字符串正确的方法是使用strcat和strcpy函数。不过要想使用这两个函数,还必须提供一个用于存放结果字符串的数组,该数组必须足够大以便容纳下结果字符串及末尾的空字符。
一个潜在的问题是,我们在估算所需的空间时不容易估准,而且所存的内容一旦改变,就必须重新检查其空间是否足够。这类代码充满了风险而且经常导致严重的安全泄露,所以一般使用标准库string,它更安全更高效。


混用string对象和C风格字符串:
允许使用字符串字面值来初始化string对象:

string s("helloworld");//s的内容是helloworld</span>

一般情况下,任何出现字符串字面值的地方都可以用空字符结束的字符数组来替代:
一.允许使用以空字符结束的字符数组来初始化string对象或为string对象赋值。
二.在string对象的加法运算中允许使用以空字符结束的字符数组作为其中一个运算对象(不能两个运算对象都是);在string对象的复合赋值运算中允许使用以空字符结束的字符数组作为右侧的运算对象。


以上性质反过来就不成立了:如果程序的某处需要一个C风格字符串,无法直接用string对象带代替它。但是string专门提供了一个名为c_str的成员函数,c_str返回的是一个C风格的字符串。也就是说,函数的返回结果是一个指针,该指针指向一个以空字符结束的字符数组,指针类型是const char*;

char *str = s;//错误:不能用string对象初始化char*const char *str=s.c_str();//正确</span>

之前介绍过不允许使用一个数组为另一个内置类型的数组赋初值,也不允许使用vector对象初始化数组。相反的,允许使用数组来初始化vector对象,只需要指明要拷贝区域的首元素地址和尾后地址:

int arr[] = {1,2,3,4,5,6,7};vector<int> vec(beagin(arr),end(arr));</span>

现代的C++程序应当尽量使用vector和迭代器,避免使用内置数组和指针,使用string,避免使用C风格的基于数组的字符串。

0 0