字符串
我们将字符串保存在char类型的字符数组中,如果char类型的字符数组以空字符\0结尾,则该数组就构成了字符串。
因为字符串需要以\0结尾,所以在定义的时候字符数组的长度要预留一个字节来存放空字符,例如:
char str[21]; //存放20个英文字符或10个汉字。
字符串要使用双引号包围起来,不能使用单引号,例如:“zunnajim”,“ABC”;
1.占用内存的情况
一个字符占用一个字节的内存,字符串定义时数组的大小决定了字符串占用的内存大小。
char str1[21]; //占用21个字节
2.字符串的初始化
1.在定义的时候初始化(后面的代码中不可以使用)
char str[20]=“zunnajim”;
2.将首字符置零
char str[20];
sr[0]=0;
3.memset 函数
char str[20];
memset(str,o,sizeof(str)); // 设置为空字符
4.strcpy函数
char str[20];
strcpy(str,“zunnajim”); //将制定的字符赋值给str
3.字符串的输出
字符串的输出控制符是%s,可以加以格式:
%ms:输出m个字符宽度,右对齐
%-ms:输出m个字符宽度,左对齐
如果字符串长度大于m,则按实际的字符长度输出
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
char str[10]="zunnajim";
printf("%20s\n",str);
printf("%-20s\n",str);
printf("%5s\n",str);
}
运行结果:
zunnajim
zunnajim
zunnajim
4.字符串越界
字符串本质上是一个字符数组,所以也可以用下标来访问其中的单个字符。所以字符串也存在数组下标越界问题。
示例1:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
char str[10]="zunnajim";
int i;
for(i=0;i<10;i++)
{
printf("%c ",str[i]);
}
strcpy(str,"zunnajim mamitimin");
printf("\n");
printf("%s",str);
运行结果:
z u n a j i m
zunnajim mamitimin
示例2:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main()
{
char str_array[2][10];
memset(str_array,0,sizeof(str_array));
strcpy(str_array[1],"我是一名中华人民共和国公民!");
strcpy(str_array[2],"武汉理工大学是一所大学!");
printf("str_array[1]=%s\n",str_array[1]);
printf("str_array[2]=%s\n",str_array[2]);
}
运行结果:
str_array[1]=我是一�武汉理工大学是一所大学!
str_array[2]=武汉理工大学是一所大学!
Segmentation fault (core dumped)
可以看出该程序报了一个段错误,在此处就是因为数组越界问题,给长度为10个bits的字符串赋值一个实际长度大于10bits的字符串时,就会出现错误。
这是因为strcpy函数再给字符串赋值的时候,源字符串(“zunnajim mamitimin”)长度如果大于目标字符串(str)的长度,其次目标字符串后面的内存是空的,就会将这一片内存划分给目标字符串(str)。如果目标字符串后面的内存已经被使用,那么就会出现Segmentation fault。就像示例2。
5.常用函数
1.获取字符串的长度(strlen)
size_t strlen(const char* str);
/*计算字符串长度,不包含\0,返回字符串的字符数,遇到第一个\0停止。如果字符串没有被初始化,那么会从字符串首地址开始查找\0,他的结果是不定的*/
sizeof()函数返回的是字符串在内存所占用的空间,并不是字符串所含有的字符串个数。
示例:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main()
{
char str1[10];
memset(str1,0,sizeof(str1));
char str2[10]="zunnajim";
char str3[20]="zunnajim mamitimin";
printf("size(str1)=%d\n",strlen(str1));
printf("size(str2)=%d\n",strlen(str2));
printf("size(str3)=%d\n",strlen(str3));
printf("sizeof(str1)=%d\n",sizeof(str1));
printf("sizeof(str2)=%d\n",sizeof(str2));
printf("sizeof(str3)=%d\n",sizeof(str3));
}
运行结果:
size(str1)=0
size(str2)=8
size(str3)=18
sizeof(str1)=10
sizeof(str2)=10
sizeof(str3)=20
2.字符串赋值或复制(strcpy)
char *strcpy(char* dest,const char* src);
/*功能:将参数src字符串拷贝至参数dest所指的地址
返回值:返回参数dest的字符串起始地址
注意:如果dest所指的内存不够大,可能造成溢出缓冲区的情况(越界)*/
3.字符串赋值或复制(strncpy)
char* strncpy(char* dest,const char* src,const size_t n);
/*
功能:把src前n个字符的内容复制到dest中
返回值:dest的起始地址
注意:如果src字符长度小于n,则拷贝完字符串之后,在dest后面追加0,直到n个
如果src字符长度大于n,就截取src的前n个字符,不会再dest后面追加0.
dest的长度必须大于n,否则可能会造成缓冲区溢出。
4.字符串拼接(strcat)
char* strcat(char* dest,char* src);
/*
功能:将 src字符串拼接到dest尾部
返回值:dest的起始地址
dest最后原有的结尾字符\0会被覆盖,并在连接后的字符串的尾部再增加一个\0。
dest要有足够大的空间,否则可能会造成缓冲区溢出。
5.字符串拼接(strncat)
/*
功能:将 src字符串前n个字符拼接到dest尾部
返回值:dest的起始地址
dest最后原有的结尾字符\0会被覆盖,并在连接后的字符串的尾部再增加一个\0。
dest要有足够大的空间,否则可能会造成缓冲区溢出。
6.字符串比较(strcmp,strncmp)
int strcmp(const char* str1,const char *str2);
/*功能:比较str1和str2的大小
返回值:str1>str2 返回大于0的数
str1=str2 返回0
str1<str2 返回小于0的数
*/
int strncmp(const char* str1,const char *str2,size_t n);
/*功能:比较str1和str2前n个字符的大小
返回值:str1>str2 返回大于0 的数
str1=str2 返回0
str1<str2 返回小于0的数。
两个字符比较的是ASCII码的大小。
7.字符查找(strchr、strrchr)
char* strchr(const char* s,int c); //返回字符串s中第一个c的地址,找不到返回0
char* strrchr(const char* s,int c); //返回字符串s中c最后出现的地址,找不到返回0
8.字符串查找(strstr)
char *strstr(const char* str,const char *str); //检索子串在字符串中首次出现的位置,返回字符串中第一次出现子串substr的地址,如果没有则返回0.
示例:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main()
{
/* char* strcpy(char* dest,const char* src);
* char* strncpy(char* dest,const char* src,size_t n);
* char* strcat(char* dest,char* src);
* char* strncat(char* dest,char* src,size_t n);
* int strcmp(const char* str1,const char *str2);
* int strncmp(const char* str1,const char *str2,size_t n);
* char* strchr(const char* s,int c);
* char* strrchr(const char* s,int c);
* char *strstr(const char* str,const char *str);
*/
char str1[10]="zunnajim";
strcpy(str1,"zunnajim");
printf("strcpy=%s\n",str1);
char str2[5];
strncpy(str2,str1,5);
printf("strncpy=%s\n",str2);
char str3[20]="zunnajim";
strcat(str3,str1);
printf("strcat=%s\n",str3);
printf("strcmp=%d\n",strcmp(str1,str2));
printf("strncmp=%d\n",strncmp(str1,str2,5));
printf("strchr(n)=%p\n",strchr(str1,'n'));
printf("strrch(n)=%p\n",strrchr(str1,'n'));
printf("strstr(unn)=%s\n",strstr(str1,"unn"));
}
运行结果:
strcpy=zunnajim
strncpy=zunna
strcat=zunnajimzunnajim
strcmp=-21
strncmp=0
strchr(n)=0x7ffe12d6e9e2
strrch(n)=0x7ffe12d6e9e3
strstr(unn)=unnajim