
void token(char name[],char list[],char token[],FILE *table) //将文件中的字符串分别切割转换为token串
{
	FILE *in,*out;
	char ch,c,buffer[N],*link[M];
	int i=0,j=0,k=0,LenLink=0;
	if((in=fopen(name,"r+"))==NULL)
	{
		printf("源文件无法打开！\n");
		exit(0);
	}
	if((out=fopen(list,"w+"))==NULL)
	{
		printf("文件写入失败！\n");
		exit(0);
	}
	if((table=fopen(token,"w+"))==NULL)
	{
		printf("文件写入失败！\n");
		exit(0);
	}
	while(!feof(in)) //逐字读取文件
	{
		ch=fgetc(in);
		if(ch=='\t' || ch==' ' || ch== '\n') continue;//去掉制表符、空格、回车 
		if(isalpha(ch)) //如果首字符是字母
		{
			while(isalnum(ch)&&(i<N)) //其他位是字母或数字
			{
				buffer[i++]=ch;
				ch=fgetc(in);
			}
			buffer[i]='\0';//串尾 
			link[j++]=(char *)malloc(sizeof(char)*(strlen(buffer)+1));
			strcpy(link[j-1],buffer);
			i=0;
			fseek(in,-1L,1); //在文件当中定位，回到前一字节处 
		}

		else if(isdigit(ch)) //如果首字符是数字
		{
			while(isalnum(ch)&&(i<N)) //其他位是字母或数字
			{
				buffer[i++]=ch;
				ch=fgetc(in);
			}
			buffer[i]='\0';
			link[j++]=(char *)malloc(sizeof(char)*(strlen(buffer)+1));
			strcpy(link[j-1],buffer);
			i=0;
			fseek(in,-1L,1);
		}

		else if(!isalnum(ch)) //如果首字符既不是数字也不是字母 
		{
			if(ch!='\n'&&ch!=' '&&ch!='\t')//不是换行、空格或制表 
			{
				if(ch=='>'||ch=='<'||ch=='!')//>=,<=,!=这些需被认为是一个符号
				{
					if((c=fgetc(in))=='=')
					{
						buffer[i++]=ch;
						buffer[i++]=c;
						buffer[i]='\0';
						link[j++]=(char *)malloc(sizeof(char)*3); strcpy(link[j-1],buffer);
						i=0;
					}
					else
					{
						buffer[i++]=ch;
						buffer[i]='\0';
						link[j++]=(char *)malloc(sizeof(char)*2); 
						strcpy(link[j-1],buffer);
						i=0;
						fseek(in,-1L,1);
					}
				}

				else if(ch=='+'||ch=='-'||ch=='&'||ch=='|'||ch=='=')//++,--,&&,||,==这些需被认为是一个符号
				{
					if((c=fgetc(in))==ch) 
					{
						buffer[i++]=ch;
						buffer[i++]=c;
						buffer[i]='\0';
						link[j++]=(char *)malloc(sizeof(char)*3); 
						strcpy(link[j-1],buffer);
						i=0;
					}
					else
					{
						buffer[i++]=ch;
						buffer[i]='\0';
						link[j++]=(char *)malloc(sizeof(char)*2); strcpy(link[j-1],buffer);
						i=0;
						fseek(in,-1L,1);
					}
				}

				else //其他符号
				{
					buffer[i++]=ch;
					buffer[i]='\0';
					link[j++]=(char *)malloc(sizeof(char)*2); 
					strcpy(link[j-1],buffer);
					i=0;
				}
			}
		}
	} 
		LenLink = j-1; //存到link中的总长度
		for(i=0;i<LenLink;i++) //打印token中的内容
		{
			c=type(link[i]);
			if(c=='N'||c=='A'||c=='R')//数字，符号在表中保留
				fputs(link[i],table);
			if(c=='C') //变量均替换为id
				fputs("id",table);
			if(c=='K')//关键字int,short,long替换为zh
				fputs("zh",table);
			if(c=='E')//关键字float,double替换为fu
				fputs("fu",table);
			if(c=='Y')//其他关键字不变
				fputs(link[i],table);
			if(c=='H')//汉字删掉
				fputs("\0",table);
		}
		fclose(table);
		fprintf(out,"\t***** 单词类型观察表 *****\n");//打印list中的内容
		fprintf(out,"\t K --int,short,long \n");
		fprintf(out,"\t E --float,double\n");
		fprintf(out,"\t Y --其他关键字\n");
		fprintf(out,"\t A --运算符号\n");
		fprintf(out,"\t R --语言符号\n");
		fprintf(out,"\t N --数字\n");
		fprintf(out,"\t H --汉字\n");
		fprintf(out,"\t C --一般变量或标识符\n");
		fprintf(out,"\t*****************************\n");
		
		for(i=0;i<LenLink;i++)
		{
			c=type(link[i]); //判断单词的类型
			fputc('(',out);
			fputc(c,out);
			fputc(',',out);
			fputs(link[i],out);
			fputc(',',out);
			fprintf(out,"%d",i);
			fputc(')',out);
			fputc('\n',out);
		}
	
} 
void simple(int MinMatchLen,FILE *fp1,FILE *fp2)//计算相似度，MinMatchLen: 公共子串要达到的最小长度
{
	SString A,B;
	char ch,h;
	int i=0,j=0,k,t,s,a=1,La,Lb,lena,lenb,x,y;
	float n;
	int MatchLen=0;//所有公共子串的总长度
	int maxmatch;//当前最大公共子串长度
	if ((fp1=fopen("token1.txt","r"))==NULL)//设定文件位于当前目录下
	{
		printf("文件打开失败！");
		getch();
		exit(0);
	}
	A[++i]=fgetc(fp1);
	while(!feof(fp1))
		A[++i]=fgetc(fp1);
	fclose(fp1);
	La=i-1;
	printf("token串1长度为%d，",La);
	if ((fp2=fopen("token2.txt","r"))==NULL)//设定文件位于当前目录下
	{
		printf("文件打开失败！");
		getch();
		exit(0);
	}
	B[++j]=fgetc(fp2);
	while(!feof(fp2))
	B[++j]=fgetc(fp2);
	fclose(fp2);
	Lb=j-1;
	printf("token串2长度为%d\n",Lb);
	printf("是否要查看这两个token串？Y/N ");
	h=getchar();
	if(h=='Y'||h=='y')
	{
		ShellExecute(NULL,"open","token1.txt",NULL,NULL,SW_SHOWNORMAL);
		ShellExecute(NULL,"open","token2.txt",NULL,NULL,SW_SHOWNORMAL);
	}
	getchar();
	printf("\n将超过指定长度的公共子串用空格替换，是否要查看细节？Y/N ");
	ch=getchar();
	lena=i-1;
	lenb=j-1;
	do{
		maxmatch=MinMatchLen;
		for(i=1;i<=La;i++)
		{
			for(j=1;j<=Lb;j++)
			{
				k=0;
				while((k<=La-i)&&(k<=Lb-j)&&(A[i+k]==B[j+k])&&((A[i+k]!='\0')||(B[j+k]!='\0'))&&(A[i+k]!=' ')&&(B[j+k]!=' '))//串A的第i+k个字符与串B的第j+k个字符是否相等 
					k++;
				if(k>maxmatch)
				{
					maxmatch=k;
					x=i;
					y=j;
				}
			}
		}
		if(maxmatch>MinMatchLen)
		{
			{
				int i;
				if(x<1||x>La-maxmatch+1||maxmatch<0)
				break;
				A[x]=' ';
				for(i=x+maxmatch;i<=La;i++)
				{
					A[i-maxmatch+1]=A[i];
				}
			}
			{
				int i;
				if(y<1||y>Lb-maxmatch+1||maxmatch<0)
				break;
				B[y]=' ';
				for(i=y+maxmatch;i<=Lb;i++)
				{
					B[i-maxmatch+1]=B[i];
				}
			}			
						
			La=La-maxmatch+1;
			Lb=Lb-maxmatch+1;
			MatchLen+=maxmatch;
		}
		if(ch=='Y'||ch=='y')
		{
			printf("第%d次检查两串中的匹配串\n",a);
			a++;
			for(s=1;s<=La;s++)
				printf("%c",A[s]);
			printf("\n");
			for(s=1;s<=Lb;s++)
				printf("%c",B[s]);
			printf("\n");
		}
	}while(maxmatch>MinMatchLen);

