C字符串
C语言不存在显式的字符串类型,C语言中的字符串都以字符串常量
的形式存储在字符数组
中
形如:
char site[7] = {'R', 'U', 'N', '\0'};
\0
标识字符数组结尾
C 中有大量操作字符串的函数:
1 、strcpy(s1, s2);
复制字符数组s2 到字符数组s1的内存空间中去
2 、strcat(s1, s2);
连接字符串 s2 到字符串 s1 的末尾。
3、 strlen(s1);
返回字符串 s1 的长度。
4、 strcmp(s1, s2);
如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回小于 0;如果 s1>s2 则返回大于 0。
5、 strchr(s1, ch);
返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
6、 strstr(s1, s2);
返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。
C++字符串
C++ 大大增强了对字符串的支持,除了可以使用C风格的字符串,还可以使用内置的 string 类。string 类处理起字符串来会方便很多,完全可以代替C语言中的字符数组
string 是 C++ 中常用的一个类,头文件< string>
常见用法:
1、初始化:
int main(){
string s1; //只是定义但没有初始化,编译器会为s1赋默认值""
string s2 = "c plus plus"; //定义加初始化,编译器在字符串末尾加上\0
string s3 = s2;
string s4 (5, 's');//s4被初始化为由 5 个's'字符组成的字符串,即"sssss"
return 0;
}
2、访问字符串中的字符
string 字符串也可以像C风格的字符串一样按照下标
来访问字符,形如s[i]
3、字符串的拼接
有了 string 类,我们可以使用+运算符
来直接拼接字符串,非常方便,再也不需要使用C语言中的 strcat()、strcpy()、malloc() 等函数来拼接字符串了,再也不用担心空间不够会溢出了。
用+来拼接字符串时,运算符的两边可以都是 string 字符串,也可以是一个 string 字符串和一个C风格的字符串,还可以是一个 string 字符串和一个字符数组,或者是一个 string 字符串和一个单独的字符。
例如:
int main(){
string s1 = "first ";
string s2 = "second ";
char *s3 = "third ";
char s4[] = "fourth ";
char ch = '@';
string s5 = s1 + s2;
string s6 = s1 + s3;
string s7 = s1 + s4;
string s8 = s1 + ch;
cout<<s5<<endl<<s6<<endl<<s7<<endl<<s8<<endl;
return 0;
}
运行结果:
first second
first third
first fourth
first @
3、增删改查
插入字符串:insert
删除字符串:erase
提取子字符串:substr
查找:find
insert详解
在原串下标为pos的字符前插入字符串str
basic_string& insert (size_type pos, const basic_string& str);
str从下标为pos1开始数的n个字符插在原串下标为pos的字符前
basic_string& insert (size_type pos, const basic_string& str, size_type pos1, size_type n);
在原串下标为pos的字符前插入n个字符c
basic_string& insert (size_type pos, size_type n, char c);
int main()
{
string str="ad";
string s="bc";
str.insert(1,s);//在原串下标为1的字符d前插入字符串s
cout<<str<<endl; //abcd
string str2="hello";
string s2="weakhaha";
str2.insert(0,s2,1,3);//将字符串s2从下标为1的e开始数3个字符,分别是eak,插入原串的下标为0的字符h前
cout<<str2<<endl;//eakhello
string str1="hello";
char c='w';
str1.insert(4,5,c);//在原串下标为4的字符o前插入5个字符c
cout<<str1<<endl;//hellwwwwwo
return 0;
}
erase详解
1、basic_string & erase(size_type pos=0, size_type n=npos);
即从给定起始位置pos处开始删除, 要删除字符的长度为n, 返回值修改后的string对象引用
int main(){
string str = "hello c++! +++";
// 从位置pos=10处开始删除,直到结尾
// 即: " +++"
str.erase(10);
cout << '-' << str << '-' << endl;
// 从位置pos=6处开始,删除4个字符
// 即: "c++!"
str.erase(6, 4);
cout << '-' << str << '-' << endl;
return 0;
}
2、iterator erase(const_iterator position)
删除迭代器位置处的单个字符, 并返回下个元素的迭代器
3、iterator erase(const_iterator first, const_iterator last)
删除迭代器[first, last)区间的所有字符,返回一个指向被删除的最后一个元素的下一个字符的迭代器.
int main(){
string str = "hello c++! +++";
// 删除"+++"前的一个空格
str.erase(str.begin()+10);
cout << '-' << str << '-' << endl;
// 删除"+++"
str.erase(str.begin() + 10, str.end());
cout << '-' << str << '-' << endl;
return 0;
}
C的四个字符串拷贝函数
strcpy(s1,s2)
strcpy的问题有:
- 复制过程中遇到结束符
\0
会结束复制 - s1的内存空间不够会内存溢出
memcpy(s1,s2,n)
memcpy()从源地址复制n 个字节到目标地址
-
memcpy() 会完整的复制 n个字节,不会遇到‘\0’而结束,这点与 strcpy() 不同
-
memcpy()并不限制被复制的数据类型,只是逐字节地进行复制,任何数据类型都可以进行复制,例如字符数组、整型、结构体、类等
-
dest 和 src所指的内存空间地址不能重叠,重叠时复制结果会覆盖
-
通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
memmove(s1,s2,n)
memmove()从源地址复制n 个字节到目标地址
最大的特点:如果目标区域和源区域有重叠的话,memmove能够保证拷贝结果不受内存重叠的影响,正确的进行拷贝,而memcpy不能做到这点。
memmove怎么做到这点的呢?
目标区域和源区域有重叠的两种情况:
1、dest所在区域在src所在区域前,直接复制即可,不会出现数据被覆盖的情况
2、dst所在区域在src所在区域后面
这种情况下如果直接复制会导致src最后的三个字节数据被覆盖,所以memmove()会先从后往前赋值
strncpy()
定义:char *strncpy(char *dest, const char *src, size_t len);
参数:
destinin:目标字符数组;
source:源字符数组;
len:复制的字符串长度。
函数说明:strncpy()复制字符串 src 的前 len 个字节到 dest所指的内存地址上。
返回值:返回字符串dest
- 如果source的长度>复制的字符串数len,则只复制source的前len个字符,不会自动添加结束符\0
- 如果source的长度<复制的字符串数len,则以
NULL
填充dest,直到复制完n个字节