包括strlen、strcmp、strcpy、strcnpy、strcat、strstr、strchr、atoi等字符串处理函数
关于头文件:在C++中应包含<string.h>(C版本头文件)或<cstring>(C++版本头文件)(两者互相对应,我猜内容大致一样?)。<string>是C++定义的std::string所使用的文件,是string类的头文件
【知识整理】string.h, string, cstring
1.strlen
原型:int strlen(char *s);
功能:计算字符串s的长度、返回s的长度,不包括结束符NULL。
2.strcmp
原型:int strcmp(const char *str1,const char * str2);
所在头文件:string.h
功能:比较字符串s1和s2;(1)当s1<s2时,返回为负数 注意不是-1;(2)当s1==s2时,返回值= 0;(3)当s1>s2时,返回正数 注意不是1
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char a = 'A';
char b = 'B';
cout << strcmp(&a,&b) << endl;
//错误示范:
cout << strcmp('A','B') << endl;
cout << strcmp(&'A',&'B') << endl;
return 0;
}
错误示范1:单引号括起来表示它是char型的,但函数需要指向char类型的指针,所以错误。
错误示范2:加了&取地址还是不行,错误提示:单目‘&’运算中的左值无效。我猜是常量不能取地址?
正确操作要像开头那样定义变量,再取地址。
3.strcpy
原型:char *strcpy(char* dest, const char *src);
功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间,返回指向dest的指针。
在linux下试验了,如果dest长度不够的话它依然进行拷贝不会报错。所以最好在用的时候加上相关的长度判断,则会大大降低出此错误的危险。
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char src[] = "afternoon...";
char dest[20] = {0};
cout << strcpy(dest,src) << endl;
cout << dest << endl;
cout << &dest << endl; //按理说应该是错的?取地址的地址,然后C++认为它是一个指向
//不知名的指针,所以输出的应该是该指针内容,但这里输出的是
//指针指向变量存放的内容
cout << endl;
cout << dest[0] << endl; //输出字符串单个字符的方法
cout << &dest[0] << endl; //dest[0]是单个字符,取地址相当于指向字符的指针了
//所以输出从该字符开始的字符串
cout << endl;
cout << dest[1] << endl;
cout << &dest[1] << endl;
cout << endl;
cout << static_cast<const void*>(dest) << endl;
return 0;
}
其实第二步之后的cout我是想输出字符串首地址的,但显然它只会输出这个字符串的内容,因为C++的cout在遇到字符型指针时会将其当作字符串名来处理,输出指针所指的字符串。既然这样,那么我们就别让它知道那是字符型指针,用void*指向字符串,cout无法知道void*指针指向的数据的解析方法,所以会输出字符串的首地址。得用到强制类型转换,不过不是C的那套,我们得用static_cast来实现,把字符串指针转换成无类型指针,这样更规范。
cout << static_cast<const void *>(dest) << endl; //括号不能少!
再补充一下单个字符输出地址之类:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int i = 'a';
cout << "int i:" << &i << endl;
char ch = 'a';
cout << "char ch:" << &ch << endl; //错误示范
cout << static_cast<void*>(&ch) << endl;
printf("char ch(c):%p\n",&ch); //p是pointer所写,以十六进制整数方式输出指针的值
printf("char ch(c):%x\n",&ch);
return 0;
}
其中的错误示范,出现原因其实之前已经提到过,即C++标准库中I/O类对输出操作符<<重载,在遇到字符型指针时会将其当做字符串名来处理,输出指针所指的字符串。 综合上述,我理解的是cout只要遇到地址,就会把它当做是一个指针。
顺便补充下在C中获取字符串首地址的方法:
printf("字符串起始地址值:%p\n", dest);
4.strncpy
原型:extern char *strncpy(char *dest, char *src, int n);
功能:把src所指由NULL结束的字符串的前n个字节复制到dest所指的数组中(应该会添加NULL)、返回指向dest的指针。如果src的长度小于n个字节,则以NULL填充dest直到复制完n个字节。
5.strcat
原型:char *strcat(char *dest,char *src);
功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'、返回指向dest的指针。
6.strstr
原型:char *strstr(const char *str1, const char *str2);
功能:实现从字符串str1中查找是否有字符串str2,如果有,从str1中的str2位置起,返回str1中str2起始位置的指针,如果没有,返回null。
7.strchr
原型:extern char *strchr(const char *s,char c);
功能:查找字符串s中首次出现字符c的位置、返回首次出现c的位置的指针,如果s中不存在c则返回NULL。
8.strrchr
原型:char *strrchr(const char *str, char c);
功能:查找一个字符c在另一个字符串str中末次出现的位置(也就是从str的右侧开始查找字符c首次出现的位置),并返回这个位置的地址。如果未能找到指定字符,那么函数将返回NULL。使用这个地址返回从最后一个字符c到str末尾的字符串。
8.strtok
原型:char *strtok(char s[], const char *delim);
功能:分解字符串为一组字符串。s为被分解的字符,delim为分隔符字符(如果传入字符串,则传入的字符串中每个字符均为分割符)。首次调用时,s指向被分解的字符串,之后再次调用要把s设成NULL。返回被字符分割成左右两部分的左边一部分的首地址。若无法再分割则返回NULL。
注意:被分割字符会发生改变,成为被分割的左半部分。但要是后续调用第一个参数都是NULL的话,被分割字符只会变一次。
这中间如果又使用了分割其他字符的strtok的函数,上一个分割函数就不再起作用了。所以要是有函数套用的时候要注意!
9.atoi
原型:int atoi(const char *nptr);
功能:把字符串转换成整型数。扫描参数nptr字符串,跳过前面的空格字符(不能是空格之外的符号比如字母之类,不然输出0),直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束符('\0')才结束转换,并将结果返回。