REASON:复习之前学习的字符串数组,同时将题目中用到的相关技巧总结到此文中,方便日后学习查阅。
·函数及用法
一.cstring字符串处理函数库
1.int strlen(char *str) 计算字符串长度
原理:从括号内给的地址开始一直到寻找到’\0’结束符为止(不计算’\0’所占的空间)
!区别:sizeof(char str)→计算整个的长度(空间),包括’\0’*
e.g.
char a[]="abcdefg";
int s=strlen(a);
int m=strlen(a+1);
int n=sizeof(a);
printf("%d %d %d",s,m,n);//7 6 8
2.int strcmp(char *a,char *b) 比较函数(字典序)
字典序:从第一位开始逐个比较其ascii值
返回值:
a>b,return 1;a=b,return 0;a<b return -1;
- char* strcpy(char *a,char *b) 赋值函数
功能:把字符串b原样复制到a,返回指针a;
原理;将字符串b从地址输入的地址开始一直到’\0’之间的部分原样复制到a中并自动带上’\0’;
关于strcpy的用法很灵活,且实际操作空间很大
4.int strcat(char *a,char *b) 连接函数
功能:把从地址b开始一直到’\0’所指字符串的内容连接到 a 所指的字符串后面(即a的‘\0’后),并自动覆盖 a 末尾的‘\0’
ps:使用此函数一定要确保a数组大小够大!
5 char* strrev(char* str) 反转函数
功能:把从地址b开始一直到’\0’所指字符串的内容颠倒反转
6.char *strchr(char *a,char ch) 字符查找函数
功能:用与查找字符 ch 在字符串 a 中出现的内存地址,如果没找到,返回空指针 NULL。
7.char *strstr(char *a,char *b) 子串查找函数
功能:用与查找字符字符串 b 在字符串 a 中最早出现的内存地址,
如果不存在,则返回 NULL。
P.S.对于strchr和strstr来说,返回的都是一个指针,因此实际要得知说所查找的字符(串)所在的位置时应该用返回的地址减去字符串首地址
ENLARGE:如何查找第2次出现的位置
此法是博主于ccf绿书上看到的,至于具体原因还是没怎么懂,望大神指导
char a[]="abcdeabfg";
char c[]="ab";
char *p;
p=strstr(a,c);//第一次出现的位置
printf("%d",p-a)//输出0
if(p!=NULL)
p=strstr(p+1,c);//第二次
printf("%d",p-a);//输出5
如法炮制,我们也可用其得到子串出现的第3次、第4次…第n次(前提是有这么多次),我们甚至可以求到子串出现的次数!
8.int sscanf(char *a,”格式控制串”,输出项)
功能:把字符串中的数据按标准输入格式输入到输入项中。(即将数字字符串变为一个整型或浮点型的数字)
e.g
char a[]="1233 0.25";
int x;
float y;
sscanf(a,"%d%f",&x,&y) ;
printf("%d %f",x,y);//1233 0.250000
所以sscanf部分等价于
(只针对整型)
char a[]="54321";
int x=0;
for(int i=0;i<strlen(a);i++)
x=x*10+a[i]-'0';//必须-'0'
printf("%d",x);//54321
p.s.
①sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。
②遇到空格会停
!!!sscanf的用法还有很多,博主只是草草了解,其他用法可自行百度;
9.int sprintf(char *a, ”格式控制串”,输出项)
功能:把格式化的输出内容,输出到字符串 a 中。
(与sscanf恰好相反,用法也类似,不再赘述)
二.cctype字符函数库
·字符串处理技巧
1.插入操作(e.g.将字符串b插入到a的第k个位子)
思路:①复制从a[k]开始的字符串至c并将a[k]赋值为’\0’→②将b连接到a后(strcat)→③将c连接至现在的a后
int k=2;
char a[]="hello",b[]="world";
char c[10];
strcpy(c,a+k);
a[k]='\0';
strcat(a,b);
strcat(a,c);
printf("%s",a);//heworldllo
以上方法还可以将b的某一子串(b[i]~b[j])插入到a,巧用‘\0’,自行尝试
2.删除操作(e.g.将a[i]~a[j]删除)
思路:①将a[j+1]开始的字符串复制到b中→②将a[i]赋值为‘\0’→③连接a和b
int i=1,j=3;
char a[]="hello";
char b[10];
strcpy(b,a+j+1);
a[i]='\0';
strcat(a,b);
printf("%s",a);//ho
3.枚举子串
- 枚举起点i和终点j
char a[]="abcdef";
char p[30][10];
int t=0;//用以记录子串个数以存储入数组
for(int i=0;i<strlen(a);i++)
for(int j=i;j<strlen(a);j++)
{
strcpy(p[++t],a+i);
p[t][j-i+1]='\0';//j-i+1即当前枚举的子串的末尾+1
}
for(int i=1;i<=t;i++)
printf("%s\n",p[i]);
核心
for(int i=0;i<strlen(a);i++)//起点
for(int j=i;j<strlen(a);j++)//终点
{
strcpy(p[++t],a+i);
p[t][j-i+1]='\0';//j-i+1即当前枚举的子串的末尾+1
}
- 枚举起点i和长度l
char a[]="abcdef";
char p[30][10];
int t=0;
for(int l=1;l<=strlen(a);l++)//枚举长度
for(int i=0;i<strlen(a);i++)//枚举起点
{
strcpy(p[++t],a+i);
p[t][l]='\0';
}
for(int i=1;i<=t;i++)
printf("%s\n",p[i]);
核心
for(int l=1;l<=strlen(a);l++)//枚举长度
for(int i=0;i<strlen(a);i++)//枚举起点
{
strcpy(p[++t],a+i);
p[t][l]='\0';
}
p.s.子串必须用字符串数组存储,另非空子串的总个数
4.回文串的判断:根据左右对称性
//法一
int ok=1;
for(int i=0,j=strlen(c)-1;i<j;i++,j--) // 根据对称性判定
if(c[i]!=c[j]) (ok=0;break;)
if(ok) printf("Yes\n");
else printf("No\n");
//法二
int t=0,i=0,j=strlen(c)-1;
while(i<j)
if(c[i++]==c[j--])t++;
if(t==strlen(c)/2)printf("yes");
else printf("no");
5.不区分大小写
全部转化为大写或小写即可
个人学习笔记,请勿转载。欢迎大神指明错误之处~
from Mr_Shadow