C++学习笔记(二)C风格字符串和string类区别和联系
来源:互联网 发布:上海威纳贸易数据 编辑:程序博客网 时间:2024/06/04 18:44
一、概述
有时候在使用字符串时,总把C++的字符串类型和C风格的字符串混淆,或者独立为不同概念,为此特定查找资料,总结两者之间的区别和联系。如有错误,恳请指出。
二、C语言中的字符串
在C语言中,对字符串的处理主要是使用字符数组(以空字符’\0’为结尾)或者是指向字符类型的指针,即用char*,但指针在实现字符串类型是较为麻烦的。用法如下:
//example 1char 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 2char *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 3class 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]; // 对空字符串自动申请存放结束标志'\0'的//加分点:对m_data加NULL 判断*m_data = '\0';}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 4string str("abcdefg"); //调用构造函数初始化strstr[0] = 'A'; //使用下标访问,可访问可修改str.at(0)='A'; //使用成员函数at()可访问可修改
但是注意使用下标一旦越界则不报任何异常,而使用at()则会报异常,当由str.length()函数得到字符串长度(不包含空字符),即可使用for遍历数组,另一种方法是使用迭代器
//example 5string 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::iterator或string::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第一个字符位置的前面rbegin和rend用于从后向前的迭代访问,通过设置迭代器string::reverse_iterator,string::const_reverse_iterator实现
四、C风格字符串和string类的转换
C++提供的由C++字符串得到对应的C风格字符串的方法是使用data()、c_str()和copy(),C风格字符串转为string则用构造函数即可。
//example 6string 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]='\0'; //使用copy函数
data()以字符数组的形式返回字符串内容,但并不添加’\0’。c_str()返回一个以‘\0’结尾的字符数组,而copy()则把字符串的内容复制或写入既有的c_string或字符数组内。
- C++学习笔记(二)C风格字符串和string类区别和联系
- c 风格字符串和string
- C风格字符串和C++string类对比 使用实例
- std::string 和 c风格字符串
- (第四章)C风格字符串和string类里的字符串的区别 动态创建数组
- C风格字符串与标准库类String 区别和转换
- c++ Prime读书笔记5(c风格字符串和string)
- 『C++ Primer学习笔记』Chapter 3——string对象、vector对象以及数组的配套类型,C风格字符串问题和处理区别
- C风格字符串和C++string对象的相互转化
- C风格字符串和C++string对象的相互转化
- c-风格字符串和string类型的字符串的异同
- c风格字符串和string使用的一些注意点
- C风格的字符串和std::string的比较
- C风格字符串和string类型的相互转换
- 不要随意混用string和C风格字符串
- string和C-风格字符串输入方式详解
- 【C++】学习笔记三十三——函数和C风格字符串
- Qt学习: 如何显示中文,QString和string以及C风格字符串的转换
- yum命令详解
- 读书笔记之计算机系统(2)
- HDU 2112 HDU Today dijkstra
- 使用ipmi进行服务器管理
- 中间层安装不上
- C++学习笔记(二)C风格字符串和string类区别和联系
- js中(function(){…})()立即执行函数写法理解
- CC2541 Timer1 不能正常分频产生正确的 PWM
- httpclient 无信任证书使用https
- HDU 2504 又见GCD
- 阶乘、斐波那契、 1的个数统计 c语言 实现备忘
- IOS-微信支付
- oracle常见报错总结
- iOS在进行网络请求的时候的网络状态的响应的判断