简介
C风格字符串是以空字符null结束的字符数组,因为标准库函数都是根据最后面的null来做是否结束的判断的,所以,后面必须加上一个null;
字符串的比较和比较结果都须使用标准库函数strcmp进行
建议
在使用标准库函数之前,必须在头文件包含处写上 #include < cstring >
使用strlen函数计算字符数的时候,返回S的长度,不包括字符串结束符null;
在使用处理C风格字符串的标准库函数strlen时,不要忘记字符串结束符null,一定要加上!!!
传递给标准库函数strcat和strcpy的第一个实参数必须有足够大的空间存放新生成的字符串,而且不要忘记预留一个null(’\0’)字符;
尽可能使用标准库类型string,少用C风格字符串
===========================================================
一、C风格字符串
1、C风格字符串简介
- C风格字符串不能归结为C语言的类型,也不能归结为C++语言的类型,而是以空字符null结束的字符数组;
char ca1[]={'C','+','+'};
char ca2[]={'C','+','+','\0'};//有null
char ca3[]="C++";//自动在末尾添加null
const char *cp="C++";//自动在末尾添加null
char *cp1=ca1;//指向数组的第一个元素,但是不是C风格字符串
char *cp2=ca2;//指向一个以null结尾的字符数组的第一个元素
// ca1和cp1都不是C风格字符串,ca1是一个不带结束符null的字符数组,指针指向它,因此,它指向的并不是以null结束的数组。
//其他都是C风格字符串
二、C风格字符串的使用
C++语言通过(const )char*类型的指针来操纵C风格字符串。
const char *cp="some value";
while(*cp)
{
++cp;
}
//如果cp所指的字符数组没有null结束符,则循环失败。这时,循环会从cp指向的位置开始读数,直到遇到内存中某处null结束符为止。
三、C风格字符串的标准库函数
-
常用标准库函数有:
strlen(s) :返回S的长度,不包括字符串结束符null;
strcmp(s1,s2):比较两个字符串s1和s2是否相同,若相同,返回0,若前者大于后者,返回正数,否则返回负数;
strcat(s1,s2) :将字符串s2连接到s1后,返回s1;
strcpy(s1,s2):s2复制给s1,返回s1;
使用这些库函数之前要包含头文件 #include < cstring>
字符串的比较和比较结果都须使用标准库函数strcmp;
-
不要忘记字符串结束符null;
标准库函数石strlen总是假定其参数字符串以null字符结束,当调用该标准库函数时,系统将会从实参ca指向的内存空间开始一直搜索结束符,直到恰好遇到null为止。
strlen返回这一段内存空间中总共有多少个字符;
char ca[]={'C','+','+'};
cout<<strlen(ca)<<endl;` //因为没有null结束符,所以这样是不对的
//在这个例子里,ca是一个没有null结束符的字符数组,则计算的结果不可预料。所以要在最后面加上一个' \0 '
- 调用者必须确保目标字符串具有足够的大小
- 传递给标准库函数strcat和strcpy的第一个实参数必须有足够大的空间存放新生成的字符串。
- 在使用strcat和strcpy函数时要预计存放字符串的空间大小的时候,一定要记住算上最后的null字符;
char largeStr[16+18+2];
strcpy(largeStr,cp1);//复制cp1到largeStr,返回largeStr
strcat(largeStr," ");//将两个字符串进行连接,返回largeStr
strcat(largeStr,cp2);
cout<<largeStr<<endl;
//问题在于我们经常会算错largeStr需要的大小。
//同样的,如果cp1或cp2所指向的字符串大小发生了变化,largeStr所需要的大小则会计算错误。
//上述代码常会导致安全漏洞,很容易出错。
- 使用strn函数处理C风格字符串
- 使用strncat和strncpy比strcat 和strcpy函数更安全
代码:略!!!!
四、尽可能使用标准库类型string
- 编写两个C风格字符串字面值,把结果存储在一个C风格字符串中,事先一定要算术null字符。
#include <iostream>
#include<string>
#include<vector>
#include<cstring> //使用下面的那些
using namespace std;
int main (){
//先定义两个字符串
const char*cp1="marry and linda";
const char*cp2="are friends";
//计算这两个串的长度,strlen函数是不计算最后面的那个空字符的
size_t len=strlen(cp1)+strlen(cp2);
//定义一个动态数组,预先估计需要的存储空间大小,最后加1的原因是存放一个空字符null在末尾
char * result_str=new char[len+1]; //加1不要忘记
strcpy(result_str,cp1);
strcat(result_str,cp2);strcat(result_str,'\0');
while(*result_str)
cout<<result_str<<endl;
delete [] result_str;//清楚内存空间!!勿忘!!!
return 0;
}
注意到后面的while循环了吗,这个语句在这里其实是有问题的,因为一直都没法结束,一直在输出“marry and linda are friends”。问题就在于这两个字符串连接之后,在最末尾是没有null('\0')结束符的,所以没法判定是否结束就一直在输出。
- 使用string连接两个字符串
#include <iostream>
#include<string>
#include<vector>
#include<cstring> //使用下面的那些
using namespace std;
int main (){
const string str1("mamjkjasdk");
const string str2("uuuuuuuu");
string result_str;
result_str=result_str+str1;
result_str=result_str+str2;
return 0;
}
显然,使用string对象比使用C风格字符串方便很多。