求助C语言编程问题(疑与缓存重叠有关)

时间:2021-09-18 01:39:24
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<memory.h>

#define MAX 81
#define ARRAY 0
#define INT 1
int index_int=5000;
#define FLOAT 2
int index_float=6000;
#define STRING 3
int index_string=7000;
#define END 4

char str88[MAX];

//节点定义
typedef struct __snode__
{
    __snode__ *next;
int index;
char *data;
} snode;
typedef struct {
char* str;
int code;
}array;


snode *nlink=NULL;
snode *flink=NULL;
snode *slink=NULL;
array save[MAX]={{"auto",1000},{"bool",1001},{"break",1002},{"case",1003},{"char",1004},{"_Complex",1005},{"const",1006},{"continue",1007},{"default",1008},{"restrict",1009},{"do",1010},{"double",1011},{"else",1012},{"enum",1013},{"extern",1014},{"float",1015},{"for",1016},{"goto",1017},{"if",1018},{"_Imaginary",1019},{"inline",1020},{"int",1021},{"iong",1022},{"register",1023},{"return",1024},{"short",1025},{"signed",1026},{"sizeof",1027},{"static",1028},{"struct",1029},{"switch",1030},{"typedef",1031},{"union",1032},{"unsigne",1033},{"void",1034},{"volatile",1035},{"while",1036},{" ",2014},{"\r",2015},{"#",2000},{"(",2001},{")",2002},{"[",2003},{"]",2004},{"'",2005},{"|",2006},{";",2007},{":",2008},{"\"",2009},{"{",2010},{"}",2011},{",",2012},{"\\",2013},{"short",3000},{"int",3001},{"long",3002},{"sighed",3003},{"unsighed",3004},{"char",3005},{"float",3006},{"double",3007},{"float_Complex",3008},{"double_Complex",3009},{"extern",3010},{"register",3011},{"static",3012},{"typedef",3013},{"+",4001},{"-",4002},{">",4003},{"<",4004},{"&",4005},{"!",4006},{"&",4007},{"*",4008},{"~",4009},{"%",4010},{"?",4011},{"^",4012},{"/",4013},{".",4014}};



//搜索数组
int search_array(char *str1)
{
int i=0;
while(i<MAX)
{
if(!strcmp(save[i].str,str1))return save[i].code;             //save是全局量
++i;
}
return 0;
}

//链表内部函数
int search(char *str2,snode *head)                                                        //至此,传送来的数据还是完好的
{
snode *p=head;
while(p){
if(!strcmp(str2,p->data))
return p->index;
p=p->next;
}
return 0;
}

//重写inseart_head
int inseart_head_int(char *str3)
{
snode* p=(snode *)malloc(sizeof(snode));
p->data=str3;
p->index=++index_int;
p->next=nlink;
nlink=p;
return p->index;
}
int inseart_head_float(char *str4)
{
snode* p=(snode *)malloc(sizeof(snode));
p->data=str4;
p->index=++index_float;
p->next=flink;
flink=p;
return p->index;
}
int inseart_head_string(char *str5)
{
snode* p=(snode *)malloc(sizeof(snode));
p->data=str5;
p->index=++index_string;
p->next=slink;
slink=p;
return p->index;
}

int inseart_head(char *str5,int type)
{
int index;
switch(type)
{
case INT:
index=inseart_head_int(str5);
break;
case FLOAT:
index=inseart_head_float(str5);
break;
case STRING:
index=inseart_head_string(str5);
}
return index;
}

snode* delete_head(snode* head)
{
snode *temp=head;
head=head->next;
delete temp;
return head;
}
void remove_all(int type)
{
switch(type){
case INT:
while(nlink)nlink=delete_head(nlink);
break; 
case FLOAT:
while(flink)flink=delete_head(flink);
break;
case STRING:
while(slink)slink=delete_head(slink);
}
}

//根据类型在链表中查找数据
//若找到,返回int型数据
//若未找到,新建节点,并返回int型数据
int search_link(char *str6,int type)
{
int temp;
switch(type)
{
case INT:
temp=search(str6,nlink);
if(!temp)
{
temp=inseart_head(str6,INT);
}
break;
case FLOAT:
temp=search(str6,flink);
if(!temp)
{
temp=inseart_head(str6,FLOAT);
}
break;
case STRING:
temp=search_array(str6);
if(temp)return temp;
temp=search(str6,slink);
if(!temp){
temp=inseart_head(str6,STRING);
}
break;
default:
return 0;
}
return temp;
}

//决定采用什么搜索方式
int search_diguish(int type,char *str7)
{
int ntemp;
if(type)
ntemp=search_link(str7,type);
else 
ntemp=search_array(str7);
return ntemp;
}


//作者: ***
int which_kind(char p){//判断字符类型
int a,b;
a=p;
if(((33<=a)&&(a<=47))||((58<=a)&&(a<=64))||((91<=a)&&(a<=94))||a==96||((123<=a)&&(a<=126)))
b=0;
else
if((48<=a)&&(a<=57))
b=1;
else if((65<=a)&&(a<=90)||a==95||((97<=a)&&(a<=122)))
b=2;
else
b=3;
return b;
}
bool same_kind(char p,char q)
{
//判断两个字符是否同类型
if(
((which_kind(p)==which_kind(q))&&which_kind(p)!=0)
||((which_kind(p)==2)&&(which_kind(q)==1))
||(which_kind(p)==1&&q=='.')
||(p=='.'&&which_kind(q)==1))
return 1;
else
return 0;
}

int read(FILE*input)
{//传出字符串
char px;
bool t=1;         
int i=1,j=0;
    memset(str88,0,MAX);
px=fgetc(input);

if(slink)
printf("\n\n+*+*+%s~~~~~~~%d~~~~\n\n",slink->data,slink->index);/*********************问题就出在这里slink->data地址与str88不相等,但是对str88的修改,导致slink->data改变******************/

str88[0]=px;
if(slink)
printf("\n\n+*+*+%s~~~~~~~%d~~~~\n\n",slink->data,slink->index);
while(t)
{
if(feof(input))
{
str88[i]='\0';
return END;
}
px=fgetc(input);
t=same_kind(str88[i-1],px);
if(t==1){
str88[i]=px;
++i;
}
}
fseek(input,-1,SEEK_CUR);
str88[i]='\0';
// __string=(char*)str;

//pan duan lei xing
if(which_kind(str88[0])==1)
{
while((str88[j])!='\0')
{
if(str88[j]=='.')
return FLOAT;
++j;
}
return INT;
}
if(which_kind(str88[0])==2)
return STRING;
return  ARRAY;
}

void output(FILE*out,int temp)
{
fprintf(out,"%d        ",temp);
fprintf(out,"%s\n",str88);
}

/*
 *主函数部分
int main(int argc,char*argv[]){
FILE *inputfile;
FILE *outputfile;
int t;
if(argc!=3){
printf("error\n");
exit(0);
}
if(!(inputfile=fopen(argv[1],"r"))){
printf("error\n");
exit(0);
}
if(!(outputfile=fopen(argv[2],"w"))){
printf("error\n");
exit(0);
}
int i=100;
while(t!=END&&(--i>0)){
t=read(inputfile,outputfile);
output(outputfile,search_diguish(t,__string));
}

remove_all(INT);
remove_all(FLOAT);
remove_all(STRING);

fclose(inputfile);
fclose(outputfile);
printf("\n\n***************************************END*****************************************\n\n");
return 0;
}*/



/*
 *测试程序__部分
int main()
{
char *str[3]={"chenhui","2.3","wo"};
int ntemp;
for(int i=0;i<3;++i){
ntemp=search_diguish(STRING,str[i]);
printf("%d",ntemp);}
   

remove_all(STRING);
return 0;
}
*/


/*测试程序__部分
 *
int main(int argc,char*argv[]){
    FILE *inputfile;
int t;
if(argc!=2){
printf("error\n");
exit(0);
}
if(!(inputfile=fopen(argv[1],"r"))){
printf("error\n");
exit(0);
    }
    while(t!=END){
t=read(inputfile);
        printf("%s %d\n",__string,t);
    }
fclose(inputfile);
    return 0;
}*/
int main(int argc,char*argv[]){
FILE *inputfile;
FILE *outputfile;
//    char*__string=NULL;
 //   char str[MAX];

int t;
if(argc!=3){
printf("error\n");
exit(0);
}
if(!(inputfile=fopen(argv[1],"r"))){
printf("error\n");
exit(0);
}
if(!(outputfile=fopen(argv[2],"w"))){
printf("error\n");
exit(0);
}
int i=10;
while(t!=END&&(--i>0)){
t=read(inputfile); 
printf("%d___++++++++__%d__+++++++__%d\n",(&slink->data),&str88) ;                                                            //此处开始丢失数据wo被换成\空格\chengfei\等等
      output(outputfile,search_diguish(t,((char*)str88)));
}

remove_all(INT);
remove_all(FLOAT);
remove_all(STRING);

fclose(inputfile);
fclose(outputfile);
printf("\n\n*******************************************END*****************************************************\n\n");
return 0;
}

12 个解决方案

#1


好长,好长!

#2


请使用论坛的 “插入源代码” 功能。

#3


好长,运行之后打印个error……

然后……

#4


关键部分我已经标出来啦

#5


不是一般的长

尝试把问题简化下?

#6


int read(FILE*input)
{//传出字符串
char px;
bool t=1;   
int i=1,j=0;
  memset(str88,0,MAX);
px=fgetc(input);

if(slink)
printf("\n\n+*+*+%s~~~~~~~%d~~~~\n\n",slink->data,slink->index);/*********************问题就出在这里slink->data地址与str88不相等,但是对str88的修改,导致slink->data改变******************/

str88[0]=px;
if(slink)
printf("\n\n+*+*+%s~~~~~~~%d~~~~\n\n",slink->data,slink->index);
while(t)
{
if(feof(input))
{
str88[i]='\0';
return END;
}
px=fgetc(input);
t=same_kind(str88[i-1],px);
if(t==1){
str88[i]=px;
++i;
}
}
fseek(input,-1,SEEK_CUR);
str88[i]='\0';

#7


代码太长没看

弱弱的问下,什么是缓存重叠?

#8


这个,真看不出来,正常的内存分配不会重叠的,应该是别的地方的问题

#9


我认为问题就是slink->data地址与str88相等,所以对str88的修改导致slink->data改变。
你看看流程是不是这样:
1. main 函数中的 output(outputfile,search_diguish(t,((char*)str88)),str88的地址被传给了search_diguish;
2. search_diguish调用search_link(str7,type),其中str7就是str88;
3. 以string为例,如果没找到则调用 temp=inseart_head(str6,STRING); 其中str6就是str88;
4. inseart_head调用inseart_head_string(str5),  其中str5就是str88;
5. 看inseart_head_string代码:
int inseart_head_string(char *str5)
{
...
p->data=str5;  
// 这句并不是p->data分配了空间并copy了str5的内容,而是直接将str5的指针赋给了p->data。所以p->data和str88指向同一块内存了。
...
}

#10


改成下面这样试试:
int inseart_head_string(char *str5)
{
...
if(NULL != str5)
{
p->data = new char[strlen(str5) + 1];
strcpy(p->data, str5)
}
...
}

#11


引用 3 楼 jackyjkchen 的回复:
好长,运行之后打印个error……

然后……


++

#12


  路   过

#1


好长,好长!

#2


请使用论坛的 “插入源代码” 功能。

#3


好长,运行之后打印个error……

然后……

#4


关键部分我已经标出来啦

#5


不是一般的长

尝试把问题简化下?

#6


int read(FILE*input)
{//传出字符串
char px;
bool t=1;   
int i=1,j=0;
  memset(str88,0,MAX);
px=fgetc(input);

if(slink)
printf("\n\n+*+*+%s~~~~~~~%d~~~~\n\n",slink->data,slink->index);/*********************问题就出在这里slink->data地址与str88不相等,但是对str88的修改,导致slink->data改变******************/

str88[0]=px;
if(slink)
printf("\n\n+*+*+%s~~~~~~~%d~~~~\n\n",slink->data,slink->index);
while(t)
{
if(feof(input))
{
str88[i]='\0';
return END;
}
px=fgetc(input);
t=same_kind(str88[i-1],px);
if(t==1){
str88[i]=px;
++i;
}
}
fseek(input,-1,SEEK_CUR);
str88[i]='\0';

#7


代码太长没看

弱弱的问下,什么是缓存重叠?

#8


这个,真看不出来,正常的内存分配不会重叠的,应该是别的地方的问题

#9


我认为问题就是slink->data地址与str88相等,所以对str88的修改导致slink->data改变。
你看看流程是不是这样:
1. main 函数中的 output(outputfile,search_diguish(t,((char*)str88)),str88的地址被传给了search_diguish;
2. search_diguish调用search_link(str7,type),其中str7就是str88;
3. 以string为例,如果没找到则调用 temp=inseart_head(str6,STRING); 其中str6就是str88;
4. inseart_head调用inseart_head_string(str5),  其中str5就是str88;
5. 看inseart_head_string代码:
int inseart_head_string(char *str5)
{
...
p->data=str5;  
// 这句并不是p->data分配了空间并copy了str5的内容,而是直接将str5的指针赋给了p->data。所以p->data和str88指向同一块内存了。
...
}

#10


改成下面这样试试:
int inseart_head_string(char *str5)
{
...
if(NULL != str5)
{
p->data = new char[strlen(str5) + 1];
strcpy(p->data, str5)
}
...
}

#11


引用 3 楼 jackyjkchen 的回复:
好长,运行之后打印个error……

然后……


++

#12


  路   过