题目:一、 学期末大家都要参加很多门课程的考试,在考试结束后,每个人都能够拿到各门考试的成绩单,你究竟学的怎么样?各门课程的平均分,最高分的课程和最低分的课程在一定程度上描述了你这学期的学习情况要求:读入一系列两元组数据<姓名,成绩>,生成一个排序的五元组<姓名,总分,平均分,最低分,最高分>,并将排序结果按照姓名的降序生成到文件。文件举例:Input files: In_3.txt<aaa,77><bbb,82><ccc.72><aaa,83><bbb,95>Output files: [Your Student No.]_3_out.txt<ccc,72,72,72,72><bbb,177,88.5.5,82,95><aaa,160,80,77,83>怎么避免读到<>和,呢 另外我的初始代码,求纠错#include<stdio.h>#include<stdlib.h>struct student{int sum;char name[25];int tmp;int num;int max;int min;};int main(){int i=0,j=0;int flag=0;char c;char temp[25];int count=1;struct student* p;FILE *input;FILE *output;p=(struct student*)malloc(sizeof(struct student));if((input=fopen("input.txt","r"))==NULL){printf("Error\n");exit(0);}c=fgetc(input);while((c=fgetc(input))!=','){temp[i]=c;i++;temp[i]='\0';}i=0;strcpy(p[0].name,temp);fscanf(input,"%d",&p[0].sum);c=fgetc(input);p[0].num=1;p[0].max=p[0].min=p[0].sum;while((c=fgetc(input))!=EOF){while(c=fgetc(input)!=','){temp[i]=c;i++;temp[i]='\0';}for(j=0;j<count;j++){ if(strcmp(temp,p[j].name)) { fscanf(input,"%d",&p[j].tmp); p[j].sum=p[j].sum+p[j].tmp; p[j].num++; p[j].max=p[j].max>p[j].tmp?p[j].max:p[j].tmp; p[j].min=p[j].min<p[j].tmp?p[j].min:p[j].tmp; break; flag=1; }}if(flag==0){ count++; p=(struct student*)realloc(p,count*sizeof(struct student)); fscanf(input,"%d",&p[0].sum); c=fgetc(input); strcpy(p[count-1].name,temp); p[count-1].num=1; p[count-1].max=p[count-1].min=p[count-1].sum;}flag=0;}fclose(input);free(p);for(j=0;j<count;j++){printf("<%s,%d,%f,%d,%d>\n",p[j].name,p[j].sum,(float)p[j].sum/p[j].num,p[j].max,p[j].min);}free(p);p=0;}
哎,我说你啊。。。。。我都不知道怎么说你好了你p是个指针,我估计你想用动态数组。。。。可是你至少搞清楚原理啊。。。。。你在这句之前p=(struct student*)realloc(p,count*sizeof(struct student));p都只是sizeof(struct student)的内存,你还来个p[j],都溢出了不跪了才怪啊还有都说了p是指针p[0].sum是什么东西?指针的用法再去看看你这个崩溃的样子就是内存出错,你没发现么?而且每次都realloc你知道开销多大么?
第一点,读一个然后再realloc多一个空间的方法似乎并不太好,最好是先开辟一个足够大的数组,但你可以说问题规模未知不知开多大也说得过去。如果是C++使用容器就好办多了。第二,如果保证输入文件格式是规范的,那么一条语句就可以同时读入姓名和分数:fscanf(input,"<%[^,],%d>\n", p[j].name, &p[j].tmp);就可以同时把姓名和分数读入并且避免读到<>和,。"<%[^,],%d>\n"是一个正则表达式,fscanf如何使用正则表达式自己百度下吧。 追问 fscanf(input,"\n", p[j].name, &p[j].tmp);会不会读到“,”到名字里面?
这个题目可以分成4个部分, 第一部分是读取数据, 当然要做到重复姓名的放在一起,第二部分是计算平均值,第三部分是排序,第四部分是写出数据,如果有这么一个思路的话, 那么整个程序就可以分为4个函数来解决,下面是我写的一个,没有写排序,才用链表的形式,#include <stdio.h>#include <stdlib.h>#include <string.h>struct student{charszName[32];///< 姓名intnTotalScore;///< 总成绩doublefAverage;///< 平均分,在计算前,可以用来计数成绩的个数intnMax;///< 最大分intnMin;///< 最小分struct student *pNext;///< 下一个};/** @fnstruct student * GetStudentInfoByName*@brief根据名字查找*@paramstruct student * pHeader链表头*@paramchar * szName名字* @returnstruct student *节点*/struct student *GetStudentInfoByName(struct student *pHeader, char *szName){struct student*pPreNode= NULL;if (pHeader == NULL || szName == NULL){return NULL;}pPreNode= pHeader;while (pPreNode != NULL){if (strcmp(pPreNode->szName, szName) == 0){return pPreNode;}pPreNode= pPreNode->pNext;}return NULL;}/** @fnvoid GetStudentInfo*@brief获取学生信息* @returnvoid*/ struct student *GetStudentInfo(){FILE*pFileIn= NULL;struct student*pHeader= NULL;struct student*pTmpNode= NULL;charszName[32]= {0};intnScore= 0;pFileIn= fopen("input.txt", "r");if (pFileIn == NULL){return;}while (fscanf(pFileIn, "<%[^,],%d>\n", szName, &nScore) != EOF){pTmpNode = GetStudentInfoByName(pHeader, szName);if (pTmpNode == NULL){// 说明没有找到pTmpNode= (struct student *) malloc(sizeof(struct student));if (pTmpNode == NULL){// 内存不够了fclose(pFileIn);return pHeader;}memset(pTmpNode, 0, sizeof(struct student));// 将节点放在头部pTmpNode->pNext= pHeader;pHeader= pTmpNode;strcpy(pTmpNode->szName, szName);pTmpNode->nMin= 100;}pTmpNode->nTotalScore += nScore;pTmpNode->fAverage++;if (pTmpNode->nMax < nScore){pTmpNode->nMax = nScore;}if (pTmpNode->nMin > nScore){pTmpNode->nMin = nScore;}}fclose(pFileIn);return pHeader;} /* * @fnvoid CalcAverageScore *@brief计算平均值 *@paramstruct student * pHeader * @returnvoid */ void CalcAverageScore(struct student *pHeader) { struct student*pNextNode= NULL;if (pHeader == NULL){return;}pNextNode= pHeader;while (pNextNode != NULL){pNextNode->fAverage= ((double)pNextNode->nTotalScore) / pNextNode->fAverage;pNextNode = pNextNode->pNext;} } /* * @fnvoid WriteInfoOut *@brief写成文件 *@paramstruct student * pHeader * @returnvoid */ void WriteInfoOut(struct student *pHeader) { struct student*pNextNode= NULL; FILE*pOutFile= NULL; if (pHeader == NULL) { return; } pOutFile = fopen("out.txt", "w"); if (pOutFile == NULL) { return; } pNextNode = pHeader; while (pNextNode != NULL) {fprintf(pOutFile, "<%s,%d,%f,%d,%d>\n", pNextNode->szName, pNextNode->nTotalScore, pNextNode->fAverage, pNextNode->nMin, pNextNode->nMax);pNextNode = pNextNode->pNext; } }int main(){struct student*pHeader= NULL;pHeader= GetStudentInfo();CalcAverageScore(pHeader);WriteInfoOut(pHeader);return 0;} 追问 正则表达式 不会使用怎么办? 追答 百度看资料。。或者看书