使用最大大小为50的固定长度数组。如果输入文件包含50个以上的学生,请打印一条消息,例如“该文件包含50个以上的学生!”并终止该程序。
我不知道如何添加它。我尝试了很多使用if / else语句的方法,但总是遇到11分段问题。请帮忙
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 50
// Function declarations
void printInfo();
int readresults(FILE*,int*, int*, int*);
void sort(float avgScore[], int stuID[], int totalStu);
float calcAvg (int score1, int score2);
void getInfo(float avgScore[], int totalStu, float* min, float* max, float* avg);
void writeSortedResults (FILE* AG_Sorted, float avgScore[], int stuID[], int totalStu);
void printdone();
int main (void)
{
// Local Declarations
FILE* AG_Midterm;
FILE* AG_Sorted;
int score1[MAX_SIZE];
int score2[MAX_SIZE];
int stuID[MAX_SIZE];
int i = 0;
int totalStu = 0;
float avgScore[MAX_SIZE];
float avg;
float min;
float max;
// Statements
printInfo();
AG_Midterm = fopen("/Users/r3spectak/Desktop/AG_Midterm.txt", "r");
if(AG_Midterm == NULL)
{
printf("\aError opening Results File\n");
return 100;
} // if open input
if(!(AG_Sorted = fopen ("/Users/r3spectak/Desktop/AG_Sorted.txt","w")))
{
printf("\aError opening Average Results file\n");
return 102;
}// if open input
i = 0;
while(readresults(AG_Midterm, &stuID[i], &score1[i], &score2[i]))//Kexy
{
avgScore[i] = calcAvg(score1[i], score2[i]);
i++;//Kexy
totalStu++;//Kexy
} //while
sort(avgScore, stuID, totalStu);//Kexy
getInfo( avgScore, totalStu, &min, &max, &avg );
printf( "\nHighest Average Score: %.2f\nLowest Average Score: %.2f\nClass Average Score : %.2f\n", max, min, avg );
printf("Total Students: %d\n", totalStu);
writeSortedResults(AG_Sorted, avgScore, stuID, totalStu);
printf("Total Students: %d\n", totalStu);
fclose(AG_Midterm);
fclose(AG_Sorted);
printdone();
return 0;
} // main
/*==================printInfo==================================
Reads data from Midterm file
Pre : Nothing
Post: Prints introduction message
*/
void printInfo()
{
// Statements
printf("Begin Calculation of Scores\n");
return ;
} // printInfo
/*===================readResults==================================
Reads data from AG_Midterm file
Pre : AG_Midterm is an open file.
stuid, score1 , score2
Post: reads score1 and score2
if data read -- returns 1
if EOF or error--returns 0
*/
int readresults(FILE* AG_Midterm, int * stuID, int *score1, int *score2)
{
// Local Variables
int i;
int items;
int ioCheck;
// Statements
ioCheck = fscanf(AG_Midterm, "%d%d%d",stuID, score1, score2);
if(ioCheck == EOF)
{
return 0;
}
else if(ioCheck != 3)
{
printf("Error reading file...\n");
return 0;
}
else
return 1;
} //readresults
/*===================sort===================================
Sorts by selecting the largest Average score in unsorted
portion of array and exchanging it with element at the
beginning of the unsorted list.=
Pre : list must contain atleast one item
Post: list rearranged largest to smallest
*/
void sort(float avgScore[], int stuID[], int totalStu)
{
// Local Declarations
int i = 0;
int j = 0;
int largest;
int tempID;
float temp;
for(i = 0; i < totalStu; i++)
{
largest = i;
for(j = i + 1; j < totalStu; j++)
{
if(avgScore[j] > avgScore[largest])
largest = j;
}
temp = avgScore[i];
tempID = stuID[i];
avgScore[i] = avgScore[largest];
stuID[i] = stuID[largest];
avgScore[largest] = temp;
stuID[largest] = tempID;
}
} // sort
/*===================calcAvg==================================
Determines the Average of the two midterm scores
Pre : score1, score2
Post: avgScore copied to addresses
*/
float calcAvg (int score1, int score2)
{
return (score1 + score2)/2.0;
} // calcAvg
/*===================getInfo==================================
Determines the Class Average,Lowest Average
and Highest Average scores
Pre : avgScore , totalStu
Post: avg , min , max
*/
void getInfo(float avgScore[], int totalStu, float* min, float* max, float* avg)
{
int i;
float sum = *min = *max = avgScore[0];
for( i = 1; i <totalStu; ++i )
{
sum += avgScore[i]; /* sum = sum + dAry[i] */
if( avgScore[i] < *min ) *min = avgScore[i]; /* update ... if applies */
if( avgScore[i] > *max ) *max = avgScore[i];
}
*avg = sum/totalStu;
return;
}
/*===================writeSortedResults==================================
Writes Average Scores after Sorting
Pre : AG_Sorted is an open file
avgScore
Post: Data written to file
*/
void writeSortedResults (FILE* AG_Sorted, float avgScore[], int stuID[], int totalStu)
{
// Local Definitions
int i;
int line = 0;
// Statements
for(i = 0; i < totalStu; i++)
{
fprintf(AG_Sorted, "%d %.2f ", stuID[i], avgScore[i]);
line++;
if(line == 8)
{
fprintf(AG_Sorted, "\n");
line = 0;
}
}
printf("\nSuccessfully write the sorted data to the new file\n");
return;
} // writeSortedResults
/*==================printDone==================================
Reads data from Midterm Score File
Pre : Nothing
Post: Prints end message
*/
void printdone()
{
// Statements
printf("End of Finalizing Scores.Thank you.\n");
return;
} // printDone
答案 0 :(得分:2)
如果我明白你的意图,那么你不仅仅想要避免像每个人似乎都在修复的超支一样;你试图在输入文件 溢出时彻底中止,但实际上没有让溢出,从而使你的进程出错。检查feof()
对你没有任何好处,因为你可能有一个换行符,一些空格,几乎任何在不的常规记录条目中保持feof()
真。
要解决您想要的结果(在文件太大的情况下中止),您可以将数据读入本地变量,只要您达到大小限制,就将它们放入数组然后;不是在阅读期间。否则中止。
int id, s1, s2;
while(readresults(AG_Midterm, &id, &s1, &s2))//Kexy
{
// we *know* we have a valid record. make sure it fits
// before dropping it in, otherwise proclaim the file too
// large and abort the whole thing.
if (i == MAX_SIZE)
{
printf("Too many scores. Aborting.\n");
exit(EXIT_FAILURE);
}
stuID[i] = id;
score1[i] = s1;
score2[i] = s2;
avgScore[i] = calcAvg(score1[i], score2[i]);
i++;//Kexy
totalStu++;//Kexy
} //while
答案 1 :(得分:1)
您可以在实际添加元素之前检查元素的当前数量加上您要添加的数量,以查看该数量是否超过50。
if ( sizeof ( array ) + newAmount ) > MAX_SIZE ) {
// Error.
}
答案 2 :(得分:1)
也许您首先阅读数据,然后检查它是否超出了您的限制(即使我一眼就看不到您检查它的位置)。当然,如果你能再读一个元素,你必须首先检查,然后阅读它;在某些时候,例如
while(i < MAX_SIZE && readresults(AG_Midterm, &stuID[i], &score1[i], &score2[i]))
然后你必须检查循环结束的原因。如果满足第一个条件,则i == MAX_SIZE,以便您可以在while之后检查它,例如
if (i == MAX_SIZE)
{
// abort with error
}
现在,这可能不是更好的方法,但解决你的问题。
答案 3 :(得分:1)
你的问题就是这个循环:
while(readresults(AG_Midterm, &stuID[i], &score1[i], &score2[i]))//Kexy
您正在读取文件结尾,这会导致i
在文件包含50个以上元素时成为无效的数组索引。
在while
语句中添加其他条件,以检查i
是否仍然在范围内,例如
while(i < MAX_SIZE && ...)