从一个文件中读取一段字符串,再输入一个的字符串,然后在读取字符串里找出录入的字符串,并把它改成大写

即``KMP子串大写替换主串对应位置。
有个学弟问我的,随手写写
注释还算全

#include <stdio.h>
#include <string.h>
#define max  25536
int c_next[max];
int v[max] = {0};//用于代替vector的用法

void pipixia(char *ptr);//皮皮虾函数天下第一!!!
int kmpSearch(char *a,char *b,int length1,int length2);

/*算法分析
@先匹配出那些地方从前往后按顺序可以获得子串位置
@对相应的可能错误录入进行鲁棒性处理
@生成子串的大写状态,注意不要有大写字母又-32的情况
@用生成的串替换子串在主串出现的位置
@将生成的最终final串输出到文件中
*/

void pipixia(char *ptr)//生成next的皮皮虾函数
{
    int n = strlen(ptr);
    int k = -1;
    int i = 0;
    c_next[0] = -1; //初始化第一位,以防无匹配情况
    while(i < n)
    {
        if(k == -1 || ptr[i] == ptr[k]) // k=-1用于指针i的移动
        {
            i++;
            k++;
            c_next[i] = k;
        }
        else 
    	   k = c_next[k];
    }
}

int kmpSearch(char *a, char *b,int length1,int length2) //匹配ab两串,a为父串
{
    int i = 0, j = 0,count=0;
    pipixia(b); //生成next数组
    while(i < length1)
    {
        if(j == -1 || a[i] == b[j])
            i++, j++;
        else
            j = c_next[j];
        if(j == length2)//完全的匹配成功了
        {
            v[count]=i-strlen(b);//将初始位置置入vector
            j = 0; //还原j的位置,初始化
            count++;
        }
    }
    return count;
}

int main ()
{
	char filename[max];//文件名
	char buff[max];//读取的文件主串
	char sbuff[max];//录入想要读取的子串
  
	printf("请输入字符文件名:");
	scanf("%s",filename);
	FILE *file1=fopen(filename,"r");
	if(!file1)
	{
		printf("File not found.\n");
		return 0;
	}
	fscanf(file1,"%s",buff);
	printf("%s\n",buff);//测试文件是否成功读入

	printf("请输入一串英文字母\n");
	scanf("%s",sbuff);
	/*printf("%s\n",sbuff);//测试字母是否成功读入*/

	int len1 = strlen (buff);//主串长度
	int len2 = strlen (sbuff);//子串长度
	/*printf("%d %d\n",len1,len2);测试对应的长度是否正确录入*/

	if(len1 < len2)//容错判断
	{
		printf("子串长于主串,不进行比较\n");
		fclose(file1);//关闭文件
		return 0;//退出程序
	}

    char Capsbuff[max];//子串字符大写
    while(len2+1)
    {
        if(sbuff[len2]>='a'&&sbuff[len2]<='z')//如果录入的是小写字母,则将此小写字母变为大写
            Capsbuff[len2]=sbuff[len2]-32;
        len2--;
    }
    //printf("%s\n",Capsbuff );//测试是否成功转化为大写字母
    //到此准备工作完成

    int size = kmpSearch(buff,sbuff,len1,len2);//调用函数进行模式匹配,并求出对应v的容量
    /*由于是c无法调用vector函数*/
   // printf("%d\n",size );检验size是否正确

    char final[max];
    int p=0,q=0;
    for (int i = 0; i < size ; ++i)
    {
        int L_next = v[i]; //取出下一个需要替换的位置
        while(p < L_next)
            final[q++] = buff[p++]; //将之前不需要替换的位置进行拼接
        for (int j = 0; j < (int) strlen(Capsbuff); ++j)
            final[q++] = Capsbuff[j]; //替换掉字符串
        p += strlen(sbuff); //重新置位置
    }

    while(p<(int) strlen(buff)) //将最后的也放进去
        final[q++] = buff[p++];
    final[q]=0;
    //puts(final);//测试用控制台显示
    //printf("一共替换了%d次!\n", size);检验替换次数

    /*写入文件*/
    printf("请输入输出文件名:");
    scanf("%s",filename);
    FILE *file2=fopen(filename,"w+");
    fputs(final,file2);
    printf("写入%s文件成功\n",filename);
    fclose(file2);
	fclose(file1);

    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值