17 c语言中关于字符串的处理
17.1 字符指针和字符数组的区别
17.1.1 字符指针
字符指针本身就是一个变量,用于存放字符串的首地址,而指向的字符串是以该地址为首地址的一块连续的内存空间中并以\0作为串的结束。字符指针它可以随意的指向其他的,另外的数组的首地址,所以说字符指针可以随意修改全部的字符,但是内部的某一个字符的修改就不是很方便,比如字符的追加,字符串的剪切一类的都不可以使用字符指针,但是字符数组都有专门的函数来处理。
字符指针的顺序是
1.分配内存给字符指针
2.分配内存给字符串
3.将字符串首地址赋值给字符指针
char *pa = "C cccc"
使用pa++可以遍历整个数组。
17.1.2 字符数组
将字符串作为数组来处理。
char str[] = "l am happy"
这种对字符数组的整体赋值只能在字符数组初始化使用,不能用于字符数组的赋值,字符数组的赋值只能对其元素赋值。下面元素的这种赋值是错的:
char str[20];
str = "i am happy";
但是可以使用函数对其赋值,比如:
char str[10];
strcpy(str,"l am happy");
也可以一个一个的对其赋值。
17.2.3 区别
区别1:指针指向的字符串,在c语言内部被当作常量,不能修改字符串本身,如果是数组字符串变量,就没有这个问题,可以修改数组的任意成员。
为什么字符串声明为指针时不能修改,声明为数组时就可以修改?
系统会将字符串的字面量保存在内存的常量区,这个区域时不允许用户修改的。声明为指针时,指针变量存储的值时一个指向常量区的内存地址,因此用户不能通过这个地址区修改常量区。但是,声明为数组时,编译器会给数组单独分配一段内存,字符串字面量会被编译器解释成字符数组,逐个字符写入这段新分配的内存之中,而这段新内存是允许修改的。
区别2:指针变量可以指向其他字符串,字符数组变量不能指向另一个字符串。
字符数组的数组名,总是指向初始化时的字符串地址,不能修改,所以声明字符数组后,不能直接用字符串赋值。
char s[10];
s = "abc"; //错误
为什么数组变量不能赋值为另一个数组?
因为数组变量所在的地址无法改变,或者说,编译器一旦为数组变量分配地址后,这个地址就绑定了这个数组变量了,这种绑定关系时不变的,即不能用赋值运算符为他重新赋值。
想要赋值,必须使用strcpy()函数,通过字符串拷贝完成赋值,数组的地址还是不变的。
char s[10]; strcpy(s,"abc");
17.2 字符数组的操作
头文件
#include<string.h>
17.2.1 strcpy() 字符串数组的复制
char str1[20] = "hello";
char str2[20];
strcpy(str2,str1);
将str1赋值到str2。
数组2的长度不能小于数组1的长度,不然hi溢出。
17.2.2 strncpy() 复制
复制指定长度的字符串
strncpy(str1,str2,n);
//将str2的前n个字符赋值到str1中,取代str1中原有的最前面n个字符,但复制的字符个数不应多余str1中原有的字符
17.2.3 strcat() 字符串的连接
char str[20] = "hello";
char str2[20] = "world";
strcat(str1,str2);
将str2连接到str1的后面,结果放在字符数组1中。函数调用会得到数组1的地址
1.字符数组1必须足够大,以便容纳连接后的新字符串
2.连接前两个字符串的后面都有’\0’,连接时将新字符串1后面的’\0’取消,只在新串最后保留’\0’.
17.2.4 strncat 连接字符串
将字符串2中前n个字符串连接到数组1中去
strncat(str1,str2,n);
strncat() 总是会在拼接结果的结尾,自动添加空字符′\0′
17.2.5 strcmp()字符串的比较
int strcmp(const char *s1,const char *s2);
字符串比较的规则是:将两个字符串自左至右逐个字符相比(按ASCII
码值大小比较),直到出现不同的字符或遇到′\0′为止。
(1) 如全部字符相同,则认为两个字符串相等。返回值为0
(2) 若出现不相同的字符,如果返回值为正数,则字符串1大;反之,返回值为负数,则字符串2大。
17.2.6 strlen() 计算长度
计算字符串的长度,不包括空字符’\0’
17.2.7 strstr() 查找
字符串的查找,在一个字符串中查找另一个字符串。
//string.h
//参数是字符串变量,返回的是size_t类型的无符号整数,一半当
//作int类型处理
size_t strlen(const char *s);
char str[10] = "china";
int s = strlen(str);
int s2 = strlen("china");
17.2.8 strtok()分割
将一个字符串分割成多个字符串
char str1[20] = "hello,world";
char *ptr = strto(str1,",");
以,为分割条件分割str1.
17.2.9 strlwr()/strupr()
strwr():将大写字母换成小写字母。
strupr():将小写字母换成大写字母。
17.2.10 总结
1.字符串操作
strcpy(p, p1) 复制字符
strncpy(p, p1, n) 复制指定长度字符串
strcat(p, p1) 附加字符串
strncat(p, p1, n) 附加指定长度字符串
strlen(p) 取字符串长度
strcmp(p, p1) 比较字符串
strcasecmp(p, p1)忽略大小写比较字符串
strncmp(p, p1, n) 比较指定长度字符串
strchr(p, c) 在字符串中查找指定字符
strrchr(p, c) 在字符串中反向查找
strstr(p, p1) 查找字符串
strpbrk(p, p1) 以目标字符串的所有字符作为集合,在当前字符串查找该集合的任一元素
strspn(p, p1) 以目标字符串的所有字符作为集合,在当前字符串查找不属于该集合的任一元素的偏移
strcspn(p, p1) 以目标字符串的所有字符作为集合,在当前字符串查找属于该集合的任一元素的偏移
2.字符串到数值类型的转换
strtod(p, ppend) 从字符串 p 中转换 double 类型数值,并将后续的字符串指针存储到 ppend 指向的 char* 类型存储。
strtol(p, ppend, base) 从字符串 p 中转换 long 类型整型数值,base 显式设置转换的整型进制,设置为 0 以根据特定格式判断所用进制,0x, 0X 前缀以解释为十六进制格式整型,0 前缀以解释为八进制格式整型
atoi(p) 字符串转换到 int 整型
atof(p) 字符串转换到 double 符点数
atol(p) 字符串转换到 long 整型
3.字符检查
isalpha() 检查是否为字母字符
isupper() 检查是否为大写字母字符
islower() 检查是否为小写字母字符
isdigit() 检查是否为数字
isxdigit() 检查是否为十六进制数字表示的有效字符
isspace() 检查是否为空格类型字符
iscntrl() 检查是否为控制字符
ispunct() 检查是否为标点符号
isalnum() 检查是否为字母和数字
isprint() 检查是否是可打印字符
isgraph() 检查是否是图形字符,等效于 isalnum() | ispunct()
17.3 基本数据类型和字符串的转换
17.3.1 sprintf()
头文件
stio.h
输出到字符串中。
char str1[20];
int a = 111,b = 222;
sprintf(str1,"%d,%d",a,b);
printf("%s",str1); //111 222
17.3.2 atof() /atoi()转换
头文件
#include<stdlib.h>
将字符串转换为浮点数
17.3.3 stoi() 转换
将字符串转换为整数