字符串
字符串函数
头文件string.h
1.求字符串长度
// An highlighted block
char p[10]="hello";
printf("字符串长度为%d",strlen(p));//输出为5;(不为10,也不是包含\0的6)
2.字符串连接
// An highlighted block
char p1[10]="hello",p2[]="world";
strcat(p1,p2);//将p2连接到p1上
puts(p1);// helloworld
///puts和printf的对比
3.字符串复制
// An highlighted block
char p1[10]="hello",p2[10];
strcpy(p2,p1);//将p1内容赋值到p2
以下的做法是错误的
char p[10]="hello",p2[10];
p2=p1;
4.字符串的比较(*)
// An highlighted block
char p1[10]="hello",p2[10]="hellow";
strcmp(p1,p2);
/*
p1和p2逐个比较直到不等或者一个结束.
三种情况,p1>p2:返回正数,p1=p2:返回0,p1<p2:返回负数
*/
5.从字符串提取特殊子串
// An highlighted block
char p1[10]="123AbcEFG123";
char buff[10];
//取数字和和大写字母
sscanf(p1,"%[1-9A-Z]",buff);
puts(buff);//123A 遇到不符合的就会停止,所以不会有后面EFG123
/*
sscanf(p1,"%d",a); //可以直接转换数据类型
printf("%d",a);
*/
//直到符号和跳过符号
sscanf(p1,"%[^A-Z]",buff);//遇到大写就停止
puts(buff);//123
sscanf(p1,"%*[A-Z]",buff);//跳过大写符号
puts(buff);//123bc123
sscanf(p1,"%*[^A-Z]",buff);//跳过非大写符号,即只要大写
puts(buff);//AEFG
可以取多个值,在txt文件的提取参数中很有用
wang wang-1-366
char *line;
while(fgets(line,100,fp)!=NULL){
sscanf(line,"[^-]-%d-%d",stu[i].name,stu[i].type,stu[i].score);
i++;
}
6.生成格式化的字符串
7.填充字符串
// An highlighted block
int p1[10];
memset(p1,0,10*sizeof(int));//将数组初始化为0
基础代码块
应该掌握一些基础的代码块
只含数字字符的字符串转数字
。
// An highlighted block
1.
atoi(str);
2.
int sum=0,sign=1;//sign用来表示正负号
if(str[0]=='+'||str[0]=='-') sign=(str[0]=='+')?1:-1;//第一个字符若是正负符号
for(int i=0;str[i]>'0'&&str[i]<'9';i++)
sum=sum*10+(str[i]-'0');
sum=sum*sign;
遍历两字符串或者母串和子串
。
// An highlighted block
int i=0;
while(s1[i]!='\0')
int j=0;
while(s2[j!='\0']){
//进行接下来的操作
}
字符串最后的指针(字符串的长度)
。
// An highlighted block
char *l=p;//l尾指针,p头指针
int len=0
while(*l!='\0'){l++;len++;}//通过判断是否为最后一个字符
字符串的连续分割 (取字符串中一些连续的特殊字符进行处理)
。
// An highlighted block
char *temp=p;
while(*temp!='\0'){
chart *temp2=temp;//temp2负责前进,temp负责记住开始位置
while(*temp2满足的条件&&temp0!='\0') temp2++;
//接下来就可以对temp到temp2的字符进行处理
//如分割单词(temp满足不是空格)、取出数字(temp2满足数字)等
//完成后temp2两种状态1.或者未‘\0’。2:或者为不满足但不是最后,分两种情况更新temp
if(*temp2!='\0') temp=temp2+1;
else temp='\0';
}
统计字符串不用字符的频数
。
方式很多种,这里选用最基础的采用两个额外数组计数
两个指针,两层遍历,外层用来遍历字符串,内层用来遍历a数组,如当前字符,a数组没有,则加入a,b新元素对应加1;若a中有,则b在a遍历到的位置元素加1
// An highlighted block
// s 字符串
char a[len],int b[len]//a数组用来记录字符,b数组用来记录相对应的频度
for(int i=0;i<len;i++) b[i]=0;//计数数组初始化为0
int k=0;//用来记录a中元素的个数
a[0]=s[0];b[0]++;k++;//第一个元素肯定是
for(int i=1;i<len;i++){//遍历字符串
int j=0;//用于遍历a数组
while(j<k&&s[i]!=a[j]) j++;//查看数组a中是否有,
if(j==k){//因为j<k跳出则a中没有
a[j]=s[i];
b[j]++;k++;
}
else b[j]++;
}
特别的,当已经告知只有小写字母时(或只有数字,只有大写字母),则仅仅需要一个数组,此事a数组可以省去,
// An highlighted block
// s 字符串,设其中只含有小写字母
int b[26]//b数组用来记录字母相对应的频度
for(int i=0;i<26;i++) b[i]=0;//计数数组初始化为0
for(int i=0;i<len;i++){//遍历字符串
int c=s[i]-'a';//c即为要加的位置
b[c]++;
}//打印时,只需要将b中不为零的打印就可以
字符串的翻转问题
1.整体翻转
。
思路:处理方式双指针的方法,两块代码。1:定位到尾指针。2:头尾交换
// An highlighted block
void Verse(char *p){
char *l=p;
while(*l!='\0') l++; //定位到尾指针
char temp;
while(p!=l){ //交换指针所指的内容
temp=*p;
*p=*l;
*l=temp;
p++;l--;
}
}
1.部分翻转
。
问题:将每个单词翻转 如输入Hello world,输出world Hello
思路:首先将所有字符翻转(dlrow olleH),再顺序的将每个单词翻转(world Hello)。
两块功能:1.翻转的函数改上边的函数,2.区分每个单词;
// An highlighted block
void Verse(char *p,char *l){//改为需要首尾两个参数,不需要再遍历到尾部
char temp;
while(p!=l){ //交换指针所指的内容
temp=*p;
*p=*l;
*l=temp;
p++;l--;
}
}
void Verse_Word(char *p){
char *l=p;
while(*l!='\0') l++; //定位到尾指针
Verse(p,l); // 所有的字符倒转
char
while(*)
}
两字符串对比的问题
1.两字符串的最长公共子串
。
思路:扫描两串,当前字符相等时,比较后面字符,直到不等,所得串与最长作对比。
// An highlighted block
void MAX_Com_Str(char t[],char s[],char c[]){//求t和s的最长公共串,c来存放
int s_len=0;int index=0;//最长长度,和最长字符串起始
int len;
int i=0,j=0;
while(s[i]!='\0'){
j=0;
while(t[j]!='\0'){
if(s[i]==t[j])//当前字符相等,则开始求最长
{
len=1;
for(k=1;i+k<strlen(s)&&j+k<strlen(t)&&s[i+k]==t[j+k];k++){
//两个字符都没有出界,且相等,(三个条件)
len++;
}
if(len>s_len){ index=i;s_len=len;}//满足则更新最大
j+=len;//二串更新
}
else j++;
}
i++;//一串更新
}
for(i=0;i<s_len;i++){//长度
c[i]=s[index+i];
}
c[len]='\0';
}