user-0 提问: realloc函数为什么如此之诡异？？？

回复:
user: user-0
content: 打开的15个学生信息的 文件c 人  和  妖 之间没有一大堆空格。

user: user-0
content: 打开的15个学生信息的 文件c 人  和  妖 之间没有一大堆空格。

user: user-1
content: 没有看到检查realloc函数是否失败的代码。

user: user-2
content: 仅供参考//输出PROG中有但LIST中没有的文本行，即集合PROG-LIST #include <stdio.h> #include <string.h> #include <stdlib.h> #include <search.h> #define MAXCHARS 512 int MAXLINES=10000,MAXLINES2; char *buf,*buf2; char PROG[256]="PROG";//程序Program需要的文件列表 char LIST[256]="LIST";//dir /b /s生成的实际文件列表List FILE *fp,*fl; int i,c,n,L,hh; int ignore_case=0; char ln[MAXCHARS]; int icompare(const void *arg1,const void *arg2) {    return stricmp((char *)arg1,(char *)arg2); } int compare(const void *arg1,const void *arg2) {    return strcmp((char *)arg1,(char *)arg2); } int main(int argc,char **argv) {     if (argc>1) strcpy(PROG,argv[1]);//命令行参数1覆盖PROG     if (argc>2) strcpy(LIST,argv[2]);//命令行参数2覆盖LIST     if (argc>3) ignore_case=1;//若存在命令行参数3，忽略大小写     if ((fl=fopen(LIST,"rt"))==NULL) {         fprintf(stderr,"Can not open %s\n",LIST);         fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);         return 1;     }     if ((fp=fopen(PROG,"rt"))==NULL) {         fclose(fl);         fprintf(stderr,"Can not open %s\n",PROG);         fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);         return 2;     }     buf=(char *)malloc(MAXLINES*MAXCHARS);     if (NULL==buf) {         fclose(fl);         fclose(fp);         fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES,MAXCHARS);         return 4;     }     n=0;     hh=0;     i=0;     while (1) {         if (fgets(ln,MAXCHARS,fl)==NULL) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",LIST,hh,MAXCHARS);             while (1) {                 c=fgetc(fl);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             strcpy(buf+i,ln);i+=MAXCHARS;             n++;             if (n>=MAXLINES) {                 MAXLINES2=MAXLINES*2;                 if (MAXLINES2==1280000) MAXLINES2=2500000;                 buf2=(char *)realloc(buf,MAXLINES2*MAXCHARS);                 if (NULL==buf2) {                     free(buf);                     fclose(fl);                     fclose(fp);                     fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES2,MAXCHARS);                     return 5;                 }                 buf=buf2;                 MAXLINES=MAXLINES2;             }         }     }     fclose(fl);     if (ignore_case) qsort(buf,n,MAXCHARS,icompare);     else qsort(buf,n,MAXCHARS,compare);     hh=0;     while (1) {         if (fgets(ln,MAXCHARS,fp)==NULL) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",PROG,hh,MAXCHARS);             while (1) {                 c=fgetc(fp);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             if (ignore_case) {                 if (NULL==bsearch(ln,buf,n,MAXCHARS,icompare)) printf("%s\n",ln);             } else {                 if (NULL==bsearch(ln,buf,n,MAXCHARS,compare)) printf("%s\n",ln);             }         }     }     fclose(fp);     free(buf);     return 0; }

user: user-3
content: ofile里，第一次空间扩充，p和stu不一样了，数据读到p里，你去打印stu自然是乱。最好是不用全局变量p...

user: user-0
content: 检查realloc函数是否失败的代码   加上了后扔是这样问题 赵4老师说的对于我有点难 怎么直接修改代码  修复这个问题：第一次打开乱码，第二次打开正常

user: user-2
content: 推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

user: user-0
content: 对不起 第一个帖子代码发错了 第二帖子      int k=10; //暂时分配100个学生的内存空间           注释内容错误 暂时分配10个 进入后输入5  打开c 显示  乱码 回到主界面 再输入5   打开c 结果就能打开正常显示的15个学生信息

user: user-0
content: 我把全部代码发一下 一个学生成绩管理  写的非常之累赘，烂 #include<stdio.h> #include<stdlib.h> #include<string.h> #define LEN sizeof(struct info) typedef struct info{ 	int num; 	char name[10]; 	char sex[5]; 	int C; 	int gaoshu; 	int xiandai; } student; int stunum;  int k;  student *p;    void show(student stu[],int n); void addinfo(student stu[]); void sfile(student stu[]);//危险原有数据注意保存  void sort(student stu[]); void numup(student stu[],int n); void numdown(student stu[],int n); void c11(student stu[],int n); void c2(student stu[],int n); void g1(student stu[],int n); void g2(student stu[],int n); void x1(student stu[],int n); void x2(student stu[],int n); void n1(student stu[],int n); void n2(student stu[],int n); void statistics(student stu[]);  void segmentation1(student stu[],int n); void segmentation2(student stu[],int n);  void segmentation3(student stu[],int n);  void head(); int ofile(student stu[]); int menu(); /*=================================================================*/ int main() {	                                  	 printf("\t\t\t学生成绩管理系统\n"); 	 int i=1,j;    int k=10; //暂时分配100个学生的内存空间       p=(student*)malloc(k*LEN);   // 结构体动态数组，实现任意成绩单 操作      while(i>0) 	{     i=menu();    switch(i) 	 { 	    case 1:addinfo(p);break; 	    case 2:sort(p);break;  	    case 3:statistics(p); break; 		case 4:sfile(p);break; 		case 5:ofile(p);break;  		case 0:i=-1; break; 		default:i=1;break;  	 } 	} 	free(p); }  void show(student stu[],int n)   /*显示函数*/ {   int i;   head();  for(i=0;i<n;i++)  printf("%d\t%s\t%s\t%d\t%d\t%d\t\n",stu[i].num,stu[i].name,stu[i].sex,stu[i].C,stu[i].gaoshu,stu[i].xiandai);  /*通过循环输出数据*/  }  void addinfo(student stu[]) { 	int i; 	printf("请输入录入学生数目\n"); 	scanf("%d",&stunum); 	for(i=0;i<stunum;i++) 	{  	printf("请输入学生学号（8位）\n");     scanf("%d",&p[i].num); 	printf("请输入学生姓名\n");     scanf("%s",p[i].name); 	printf("请输入学生性别\n"); 	scanf("%s",p[i].sex);  //本身地址不用取地址     	printf("请输入C语言成绩\n");     scanf("%d",&p[i].C); 	printf("请输入线代成绩\n");     scanf("%d",&p[i].gaoshu); 	printf("请输入高数成绩\n"); 	scanf("%d",&p[i].xiandai); 	} 	show(stu,stunum) ; 	getchar();  //不用的话 空格带入缓冲区 造成目录循环你可以感受一下 } void sfile(student stu[]) { 	int i=0; 	char filename[20]; 	FILE* fp; 	printf("请输入文件名\n"); 	gets(filename);  	fp=fopen(filename,"w");         fprintf(fp,"%d\n",stunum);   	for(i=0;i<stunum;i++) 	fprintf(fp,"%d %s %s %d %d %d",p[i].num,p[i].name,p[i].sex,p[i].C,p[i].gaoshu,p[i].xiandai);  //一会加头 	fclose(fp);  	printf("已存储\n");  } int ofile(student stu[]) { 	int l=10; 	int i=0; 	char k[2]; //K为显示控制 	FILE* fp; 	char filename[20]; 	printf("请输入默认路径文件名或者文件路径:\n");      gets(filename);      stunum=0;      if((fp=fopen(filename,"rb+"))==NULL)   //rb---r 	{      printf("无法打开文件\n");      return(-1); 	}    fscanf(fp,"%d",&stunum);   if(stunum>l)  {   	l=l+50;  	p=(student*)realloc(p,l*LEN);}   fgetc(fp);      while(i<stunum)  	{      fscanf(fp,"%d",&p[i].num);      fscanf(fp,"%s",p[i].name);      fscanf(fp,"%s",p[i].sex);      fscanf(fp,"%d",&p[i].C);      fscanf(fp,"%d",&p[i].gaoshu);      fscanf(fp,"%d",&p[i].xiandai);      i++;  	}      fclose(fp);     	printf("文件读取成功\n"); 	printf("是否显示文件内容？(是y)"); 	gets(k); 	if(k[0]=='y'||k[0]=='Y')     show(stu,stunum);     else  	return(0); } int menu() { 	char m;     printf("请选择\n");     printf("1、录入    2、排序    3、统计    4、保存    5、打开    0、退出\n") ;    	m=getchar();//这里不加getchar就等死吧  	getchar();  	return (m-'0'); } void head() {  printf("学号\t        姓名\t性别\tC语言\t高数\t线代\t\n"); } void sort(student stu[]) { 	int i;  	char j;   printf("请输入排序方式\n");  printf("1、学号 2、姓名 3、成绩\n"); //为什么不敢用数字  i=getchar();  getchar();  i=i-'0';   //用再get下么     switch(i)    { case 1: {  printf("1、升序 2、降序\n");  j=getchar();  getchar();  if(j-'0'==1)   //这里如果赋值就会两个都执行 千万别赋值  {numup(p,stunum);} else {numdown(p,stunum);} break;  case 3: printf("请选择排序的科目:\n"); printf("1、C语言  2、高数  3、线代:\n"); int x; char c1; x=getchar(); getchar(); if(x-'0'==1) {printf("请选择排序方式:1、升序 2、降序\n");  c1=getchar(); getchar(); if(c1-'0'==1) c11(p,stunum); if(c1-'0'==2) c2(p,stunum); } if(x-'0'==2) { printf("请选择排序方式:1、升序 2、降序\n");  c1=getchar(); getchar(); if(c1-'0'==1) g1(p,stunum); if(c1-'0'==2) g2(p,stunum); } if(x-'0'==3) { printf("请选择排序方式:1、升序 2、降序\n");  c1=getchar(); getchar(); if(c1-'0'==1) x1(p,stunum); if(c1-'0'==2) x2(p,stunum); } break;  case 2: printf("请选择排序方式:1、升序 2、降序\n");  j=getchar();  getchar();  if(j-'0'==1)   {n1(p,stunum);} else {n2(p,stunum);} break;  }    } } /*======================= 排序=========================*/  void numup(student stu[],int n) { int i; student r; bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].num>p[i+1].num)   {   	r=p[i]; //即将更改故保存    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } }  show(stu,stunum); } void numdown(student stu[],int n) { int i; student r;   bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].num<p[i+1].num)   {   	r=p[i];    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } } show(stu,stunum);	 } void c11(student stu[],int n) { int i; student r; bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].C>p[i+1].C)   {   	r=p[i];    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } }  show(stu,stunum); } void c2(student stu[],int n) { int i; student r;   bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].C<p[i+1].C)   {   	r=p[i];    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } } show(stu,stunum);	 } /*               高                           */ void g1(student stu[],int n) { int i; student r; bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].gaoshu>p[i+1].gaoshu)   {   	r=p[i];    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } }  show(stu,stunum); } void g2(student stu[],int n) { int i; student r;   bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].gaoshu<p[i+1].gaoshu)   {   	r=p[i];    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } } show(stu,stunum);	 } //                               xiand void x1(student stu[],int n) { int i; student r; bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].xiandai>p[i+1].xiandai)   {   	r=p[i]; //即将更改故保存    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } }  show(stu,stunum); } void x2(student stu[],int n) { int i; student r;   bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].xiandai<p[i+1].xiandai)   {   	r=p[i]; //即将更改故保存    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } } show(stu,stunum);	 }  //                        字符串姓名排序  void n1(student stu[],int n) { int i,j,k; student r; for(i=0;i<n-1;i++) { j=i; for(k=i+1;k<n;k++) if(strcmp(p[i].name,p[k].name)>0)   j=k;  r=p[i]; p[i]=p[j]; p[j]=r; } show(stu,stunum);	 }  void n2(student stu[],int n) { int i,j,k; student r; for(i=0;i<n-1;i++)   { j=i; for(k=i+1;k<n;k++) if(strcmp(p[i].name,p[k].name)<0) j=k; r=p[i]; p[i]=p[j]; p[j]=r;   }   show(stu,stunum);	 } /*  -  -----------       统计函数 -----------           */  void statistics(student stu[]) { printf("请选择统计内容：\n"); printf("(1)分段成绩单计数 (2)优秀成绩单 (3)不及格成绩单\n") ; int m; int i; i=getchar(); getchar(); i=i-'0'; switch(i) { 	case 1:printf("请选择分段计数的成绩\n") ; 	printf("1、C语言   2、高数   3、线代\n") ; m=getchar(); getchar(); m=m-'0'; if(m==1) 	segmentation1(p,stunum);  if(m==2) 	segmentation2(p,stunum);  if(m==3) 	segmentation3(p,stunum);  	case 2:;break; 	case 3:;break; } } void segmentation1(student stu[],int n)//这里分段用不用打出内容而不是单计数 { int i; int a[10]={0}; for(i=0;i<n;i++) { if(p[i].C<=10) a[0]++;  if((p[i].C>=11)&&(p[i].C<=20))   a[1]++;  if(p[i].C>=21&&p[i].C<=30)    a[2]++;  if(p[i].C>=31&&p[i].C<=40)   a[3]++;  if(p[i].C>=41&&p[i].C<=50)   a[4]++;  if(p[i].C>=51&&p[i].C<=60)  a[5]++;  if(p[i].C>=61&&p[i].C<=70)    a[6]++;  if(p[i].C>=71&&p[i].C<=80)   a[7]++;  if(p[i].C>=81&&p[i].C<=90)   a[8]++;  if((p[i].C>=91)&&(p[i].C<=100))  a[9]++;  } printf("各分段人数为：\n"); printf("0~10：%d   11~20：%d   21~30：%d   31~40：%d   41~50：%d   51~60：%d   61~70：%d\n",a[0],a[1],a[2],a[3],a[4],a[5],a[6]) ;  printf("71~80：%d   81~90：%d   91~100：%d\n",a[7],a[8],a[9] ); } void segmentation2(student stu[],int n)//这里分段用不用打出内容而不是单计数 { int i; int a[10]={0};  for(i=0;i<n;i++) { if(p[i].gaoshu<=10) a[0]++;  if(p[i].gaoshu>=11&&p[i].gaoshu<=20)   a[1]++;  if(p[i].gaoshu>=21&&p[i].gaoshu<=30)    a[2]++;  if(p[i].gaoshu>=31&&p[i].gaoshu<=40)   a[3]++;  if(p[i].gaoshu>=41&&p[i].gaoshu<=50)   a[4]++;  if(p[i].gaoshu>=51&&p[i].gaoshu<=60)  a[5]++;  if(p[i].gaoshu>=61&&p[i].gaoshu<=70)    a[6]++;  if(p[i].gaoshu>=71&&p[i].gaoshu<=80)   a[7]++;  if(p[i].gaoshu>=81&&p[i].gaoshu<=90)   a[8]++;  if(p[i].gaoshu>=91&&p[i].gaoshu<=100)  a[9]++;  } printf("各分段人数为：\n"); printf("0~10：%d   11~20：%d   21~30：%d   31~40：%d   41~50：%d   51~60：%d   61~70：%d\n",a[0],a[1],a[2],a[3],a[4],a[5],a[6]) ;  printf("71~80：%d   81~90：%d   91~100：%d\n",a[7],a[8],a[9] ); } void segmentation3(student stu[],int n)//这里分段用不用打出内容而不是单计数 { int i; int a[10]={0};  for(i=0;i<n;i++) { if(p[i].xiandai<=10) a[0]=a[0]+1;  if((p[i].xiandai>=11)&&(p[i].xiandai<=20))   a[1]=a[1]+1;  if(p[i].xiandai>=21&&p[i].xiandai<=30)    a[2]++;  if(p[i].xiandai>=31&&p[i].xiandai<=40)   a[3]++;  if(p[i].xiandai>=41&&p[i].xiandai<=50)   a[4]++;  if(p[i].xiandai>=51&&p[i].xiandai<=60)   a[5]++;  if(p[i].xiandai>=61&&p[i].xiandai<=70)    a[6]++;  if(p[i].xiandai>=71&&p[i].xiandai<=80)   a[7]++;  if(p[i].xiandai>=81&&p[i].xiandai<=90)   a[8]++;  if(p[i].xiandai>=91&&p[i].xiandai<=100)  a[9]++;  } printf("各分段人数为：\n"); printf("0~10：%d   11~20：%d   21~30：%d   31~40：%d   41~50：%d   51~60：%d   61~70：%d\n",a[0],a[1],a[2],a[3],a[4],a[5],a[6]) ;  printf("71~80：%d   81~90：%d   91~100：%d\n",a[7],a[8],a[9] ); }  这里是打开的成绩文件（15个学生） 15 12345678 abc 男 11 11 11 81234567 aceb 女 22 22 22 81234567 asiaaa 女 28 29 30 10000001 wsc 人妖 100 100 100 10310001 cab 人妖 99 99 99 12345678 abc 男 11 11 11 81234567 aceb 女 22 22 22 81234567 asiaaa 女 28 29 30 10000001 wsc 人妖 100 100 100 10310001 cab 人妖 99 99 99 12345678 abc 男 11 11 11 81234567 aceb 女 22 22 22 81234567 asiaaa 女 28 29 30 10000001 wsc 人妖 100 100 100 10310001 cab 人妖 99 99 99