我是靠谱客的博主 尊敬仙人掌,最近开发中收集的这篇文章主要介绍C++学习笔记(二)C风格字符串和string类区别和联系一、概述二、C语言中的字符串三、C++中的字符串四、C风格字符串和string类的转换,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、概述

有时候在使用字符串时,总把C++的字符串类型和C风格的字符串混淆,或者独立为不同概念,为此特定查找资料,总结两者之间的区别和联系。如有错误,恳请指出。

二、C语言中的字符串

在C语言中,对字符串的处理主要是使用字符数组(以空字符’’为结尾)或者是指向字符类型的指针,即用char*,但指针在实现字符串类型是较为麻烦的。用法如下:

//example 1
char str[15]="Hello world!"; //使用字符数组, 也可以char str[] ="Hello world!";
*(str+2)=’L’;
//使用*()指定数组修改位置改变第3个字母
char *p= str;
//使用指针p指向数组str的首地址
*(p+2)=’L’;
//仍可间接修改数组str的第3个字母
char *ptr ="Hello world!";
//使用指针指向一行字符串;
*(ptr+2)='L';
//错误,编译虽通过,但无法改变字符串的第3个字母

这是因为第一个字符串是由数组str开辟的,数组的每个值是可以改变的变量,而第二个指针ptr指向的是字符串常量,而字符串常量是无法改变的,故为了避免误判,指向字符串常量时应该使用const指针。

const char *ptr ="Hello world!"

//example 2
char *ptr = new char[15];
//由new在堆中开辟的15个char型空间,ptr指向该空间首地址
ptr = "abcdefg";
//错误,不可再用ptr指向另一行字符串首地址
ptr[0]='A';
//可由ptr[下标]或*(ptr+索引)写或读数据,用后者指针的形式速度较快
*ptr ='a';
//可改变ptr[0]的值
由于是堆分配的内存,故函数调用结束后,不会自行撤销,故需要在函数加入delete []ptr ;语句。


三、C++中的字符串

   由于C风格字符串较为复杂,不适合大程序的开发,故C++标准库定义了string类,头文件形式为#include <string>,而头文件<string.h>和<cstring>都是错误的,这两个头文件主要定义处理C风格字符串的一些方法,譬如strlen(), strcpy()等。第一个为C的头文件格式,第 2个为C++的C风格头文件。

    先看sting类的原形:

//example 3
class String
{
public:
String(const char *str = NULL);// 普通构造函数
String(const String &other); //拷贝构造函数
~ String(void); //析构函数
String & operator =(const String &other);//赋值函数
private:
char *m_data;// 用于保存字符串
};
//普通构造函数
String::String(const char *str)
{
if(str==NULL)
{
m_data = new char[1]; // 对空字符串自动申请存放结束标志''的//加分点:对m_data加NULL 判断
*m_data = '';
}
else
{
int length = strlen(str);
m_data = new char[length+1]; // 若能加 NULL 判断则更好
strcpy(m_data, str);
}
}
// String的析构函数
String::~String(void)
{
delete[] m_data; // 或delete m_data;
}
//拷贝构造函数
String::String(const String &other) // 输入参数为const型
{
int length = strlen(other.m_data);
m_data = new char[length+1]; //对m_data加NULL 判断
strcpy(m_data, other.m_data);
}
//赋值函数
String & String::operator =(const String &other) // 输入参数为const型
{
if(this == &other) //检查自赋值
return *this;
delete[] m_data; //释放原有的内存资源
int length = strlen( other.m_data );
m_data = new char[length+1]; //对m_data加NULL 判断
strcpy( m_data, other.m_data );
return *this; //返回本对象的引用
}

可看成string类含有一个私有的指针char* m_data,由构造函数和拷贝构造函数用new开辟空间,并用strcpy复制传进来的字符串(C风格或string类对象),由析构函数释放内存。

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

a) strings;  //生成一个空字符串s

b) strings(str) //拷贝构造函数 生成str的复制品,str为string类的对象

c) strings(str,stridx) //将字符串str内“始于位置stridx”的部分当作字符串的初值

d) strings(str,stridx,strlen) //将字符串str内“始于stridx且长度顶多strlen”的部分作为字符串的初值

e) strings(cstr) //将C风格字符串作为s的初值

f)string s(chars,chars_len) //将C风格字符串前chars_len个字符作为字符串s的初值。

g) strings(num,c) //生成一个字符串,包含num个c字符,c是字符型

h) strings(beg,end) //以区间beg;end(不包含end)内的字符作为字符串s的初值

i) s.~string()//销毁所有字符,释放内存

 

(2)字符串操作函数

a)=,assign()   //赋以新值

b)swap()   //交换两个字符串的内容

c)+=,append(),push_back() //在尾部添加字符

d)insert() //插入字符

e)erase() //删除字符

f)clear() //删除全部字符

g)replace() //替换字符

h)+ //串联字符串

i)==,!=,<,<=,>,>=,compare()  //比较字符串

j)size(),length()  //返回字符数量

k)max_size() //返回字符的可能最大个数

l)empty()  //判断字符串是否为空

m)capacity() //返回重新分配之前的字符容量

n)reserve() //保留一定量内存以容纳一定数量的字符

o)[ ], at() //存取单一字符

p)>>,getline() //从stream读取某值

q)<<  //将谋值写入stream

r)copy() //将某值赋值为一个C_string

s)c_str() //将内容以C_string返回

t)data() //将内容以字符数组形式返回

u)substr() //返回某个子字符串

v)查找函数

w)begin()end() //提供类似STL的迭代器支持

x)rbegin() rend() //逆向迭代器

y)get_allocator() //返回配置器

   这些成员函数给string字符串的操作带来了极大的方便。

(3)元素读写

//example 4
string str("abcdefg");
//调用构造函数初始化str
str[0] = 'A';
//使用下标访问,可访问可修改
str.at(0)='A';
//使用成员函数at()可访问可修改

但是注意使用下标一旦越界则不报任何异常,而使用at()则会报异常,当由str.length()函数得到字符串长度(不包含空字符),即可使用for遍历数组,另一种方法是使用迭代器

	//example 5
string s = "abcdefg";
for(string::iterator iter = s.begin(); iter!=s.end(); iter++)
//向前遍历
{
cout<<*iter<<endl;
}
for(string::reverse_iterator iter = s.rbegin(); iter!=s.rend(); iter++)
//向后遍历
{
cout<<*iter<<endl;
}

string类提供了向前和向后遍历的迭代器iterator,迭代器提供了访问各个字符的语法,类似于指针操作,迭代器不检查范围。

string::iteratorstring::const_iterator声明迭代器变量,const_iterator不允许改变迭代的内容。常用迭代器函数有:

const_iterator begin()const;

iteratorbegin();               //返回string的起始位置

const_iterator end()const;

iteratorend();                   //返回string的最后一个字符后面的位置

const_iterator rbegin()const;

iteratorrbegin();               //返回string的最后一个字符的位置

const_iterator rend()const;

iteratorrend();                   //返回string第一个字符位置的前面rbeginrend用于从后向前的迭代访问,通过设置迭代器string::reverse_iterator,string::const_reverse_iterator实现

四、C风格字符串和string类的转换

    C++提供的由C++字符串得到对应的C风格字符串的方法是使用data()、c_str()和copy(),C风格字符串转为string则用构造函数即可。

	//example 6
string var = "abcdefg";
const char *p = var.c_str();
//不加const则不正确,p所指向的字符是不可改变的
string str = "abcdefg";
char p[10];
strcpy(p,str.c_str());
p[0] ='A';
//因为p为长度10数组,故p所指向的值可改变
char *p = new char[str.length()+1];
strcpy(p ,str.data());
delete []p;
//使用data()函数
char
p[10];
str.copy(p,7);
p[str.length()+1]='';
//使用copy函数


data()以字符数组的形式返回字符串内容,但并不添加’’。c_str()返回一个以‘’结尾的字符数组,而copy()则把字符串的内容复制或写入既有的c_string或字符数组内。






最后

以上就是尊敬仙人掌为你收集整理的C++学习笔记(二)C风格字符串和string类区别和联系一、概述二、C语言中的字符串三、C++中的字符串四、C风格字符串和string类的转换的全部内容,希望文章能够帮你解决C++学习笔记(二)C风格字符串和string类区别和联系一、概述二、C语言中的字符串三、C++中的字符串四、C风格字符串和string类的转换所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部