【发布时间】:2012-03-18 01:26:39
【问题描述】:
嗯,不确定这个标题是否有意义。 我正在创建一个从文件marks.txt 中读取信息的程序(顺便说一句,这是家庭作业,所以请耐心等待我还在黑暗中徘徊:))
marks.txt:
U08006 3 30 40 30
12000001 55 42 60
12000002 37 45 40
12000003 58 0 24
12000004 74 67 80
12000005 61 50 38
12000006 70 45 58
99999999
第一行是模块代码,后面是分配的数量和每个分配的权重。其他行是学生编号,后跟每项作业的分数。最后以学生号 99999999 表示列表的末尾。
编辑:程序最终应输出每个作业和整个模块标记的学生人数以及平均值和标准差。我还被指示使用结构数组。
我已经将模块信息存储在一个结构(模块)中,但是在存储学生信息时我真的迷路了。我需要为学生提供一个结构数组,但问题是我不知道文件中有多少学生(显然我现在知道,但是如果我希望我的程序能够读取文件,即使数字的学生更改具有固定大小的数组没有帮助)。
我在想也许我可以计算文件中第一行和最后一行之间的行数。然后使用 malloc 为数组分配内存?我在正确的轨道上吗?所以像 student = malloc(sizeof(student???) * 行数)
这真的让我很困惑!同时处理指针数组结构和文件真的让我一头雾水,这是我下一堂课的时间,所以不能向我的导师寻求帮助。因此,任何提示将不胜感激。
到目前为止,我的代码“正在进行中”: 编辑:好的,所以我已经完成了该程序,即它完成了它应该做的事情,但我仍在为整个 malloc 事情苦苦挣扎。对于我的学生结构,我想要一个结构数组,并且我想在确定学生人数后分配内存,但我不确定我应该如何做到这一点?!这个指向结构数组的整个指针我不太明白,所以下面的代码不起作用。 (如果我有一个预定大小的 struct student 数组,一切都很漂亮)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int studentCount();
void getModuleDetails(FILE *fileptr);
void getStudentDetails(FILE *fileptr, int classSize);
void overallMarks(int classSize);
void cleanUp(FILE *fileptr, int classSize);
void printModuleStats(int classSize);
struct ModuleSpec {
char moduleCode[7];
int numOfAssign; /*number of assignments*/
int *assignWeighting; /*assignment weighting*/
} module; /*declare struct with variable name module*/
struct StudentMarks {
int studentNumber;
int *assignMark; //assignment mark
int moduleMark; //overall mark for module
}*student;
/*******************************************************************************************/
int main() {
int i; /*index*/
FILE *pFile;
int studentCounter = studentCount(); //count number of students in class
student = malloc(sizeof(student)*studentCounter); /*allocate memory for array of student structs*/
pFile = fopen("marks.txt", "r"); /*open file marks.txt for reading*/
if(pFile==NULL){ /*check if file was opened successfully*/
printf("File could not be opened!");
exit(EXIT_FAILURE);
}
getModuleDetails(pFile); //get module details from pFile and store in struct module
getStudentDetails(pFile, studentCounter); //get student details from pFile and store in student array fo structs
overallMarks(studentCounter); //calculate and print overall marks of students
printModuleStats(studentCounter);
cleanUp(pFile, studentCounter);
return 0;
}
/*****************************************************************************************/
int studentCount(){
FILE *pFile;
int temp;
int studentCount = 0;
pFile = fopen("marks.txt", "r"); /*open file marks.txt for reading*/
if(pFile==NULL){ /*if file can't be opened*/
printf("File could not be opened!");
exit(EXIT_FAILURE);
}
do{
temp = fgetc(pFile);
if(temp == '\n'){
studentCount++;
}
}while(temp != EOF);
studentCount -=2; /*subtract first and last lines to count only students*/
//printf("The number of students on this module is: %d\n", studentCount);
fclose(pFile);
return studentCount;
}
/*******************************************************************************************/
void getModuleDetails(FILE *fileptr){
int i;
int sumWeighting = 0;
fscanf(fileptr, "%s %d", module.moduleCode, &module.numOfAssign);
printf("Module code: %s\n", module.moduleCode);
printf("Number of assignments: %d\n", module.numOfAssign);
module.assignWeighting = malloc(module.numOfAssign * sizeof(int)); /*Allocate memory to hold assignment weightings*/
if (module.assignWeighting == NULL) { /*check if memory allocation was successful*/
printf("Memory allocation failed.");
exit(EXIT_FAILURE);
}
/*get weighting for each assignment and store in module.assignWeighting*/
for(i=0;i<module.numOfAssign;i++){
fscanf(fileptr, "%d", &module.assignWeighting[i]);
//printf("module %d %d\n", i+1, module.assignWeighting[i]);
sumWeighting += module.assignWeighting[i];
}
/*check if sum of weighting equals 100*/
if(sumWeighting != 100){
printf("Error: Sum of weighting = %d\n Expected sum: 100\n", sumWeighting);
}
}
/*********************************************************************************************/
void getStudentDetails(FILE *fileptr, int classSize){
int i;
int j;
for(i=0;i<classSize;i++){
student[i].assignMark = (int *)malloc(sizeof(int) * module.numOfAssign);
if(student[i].assignMark == NULL) { //check if memory allocation was successful
printf("Memory allocation failed.");
exit(EXIT_FAILURE);
}
fscanf(fileptr, "%d", &student[i].studentNumber);
/*get student assignment marks*/
for(j=0;j<module.numOfAssign;j++){
fscanf(fileptr, "%d", &student[i].assignMark[j]);
//printf("mark for assignment %d: %d\n", j+1, student[i].assignMark[j] );
/*check if mark is within range 0 to 100*/
if(student[i].assignMark[j]<0 || student[i].assignMark[j]>100){
printf("Error: Assignment mark is not within the range 0 to 100");
}
}
}
}
/************************************************************************************************/
void overallMarks(int classSize){
int i;
int j;
float temp;
for(i=0;i<classSize;i++){
printf("Overall mark for student %d: \n", student[i].studentNumber);
for(j=0;j<module.numOfAssign;j++){
temp += (float)(module.assignWeighting[j] * student[i].assignMark[j]) / 100;
}
student[i].moduleMark = temp + 0.5; /*add 0.5 for rounding as converting float to int rounds down*/
printf("%d%%", student[i].moduleMark);
if(student[i].moduleMark<25){
printf(" is a FAIL\n");
}
else if(student[i].moduleMark<40){
printf(" is a RESIT\n");
}
else if(student[i].moduleMark<55){
printf(" is a PASS\n");
}
else if(student[i].moduleMark<70){
printf(" is a MERIT\n");
}
else if(student[i].moduleMark<100){
printf(" is a DISTINCTION\n");
}
temp = 0;
}
}
/***********************************************************************************************/
void printModuleStats(int classSize){
int i;
int j;
float averageDevMarks;
float stdDevMarks;
float averageDevModule;
float stdDevModule;
printf("\nModule Statistics for %s\n", module.moduleCode);
printf("\nNumber of students: %d\n", classSize);
/*assignments*/
for(i=0;i<module.numOfAssign;i++){
printf("\nAssignment %d:\n", i+1);
for(j=0;j<classSize;j++){
averageDevMarks += student[j].assignMark[i];
}
averageDevMarks /= classSize;
printf("Average deviation: %f\n", averageDevMarks);
for(j=0;j<classSize;j++){
stdDevMarks += (student[j].assignMark[i] - averageDevMarks)*(student[j].assignMark[i] - averageDevMarks);
}
stdDevMarks = sqrt(stdDevMarks/classSize);
printf("Standard deviation: %f\n", stdDevMarks);
stdDevMarks = 0;
averageDevMarks = 0;
}
/*modules*/
for(i=0;i<classSize;i++){
averageDevModule += student[i].moduleMark;
}
averageDevModule /= classSize;
printf("\nAverage deviation for module mark: %f\n", averageDevModule);
for(i=0;i<classSize;i++){
stdDevModule += (student[i].moduleMark - averageDevModule)*(student[i].moduleMark - averageDevModule);
}
stdDevModule = sqrt(stdDevModule/classSize);
printf("Standard deviation for module mark: %f\n", stdDevModule);
}
/************************************************************************************************/
void cleanUp(FILE *fileptr, int classSize){
int i;
fclose(fileptr); /*close file*/
/*free previously allocated memory*/
free(student);
free(module.assignWeighting);
for(i=0;i<classSize;i++){
free(student[i].assignMark);
}
}
【问题讨论】:
-
你需要对marks.txt中的数据做什么?一旦我们了解程序需要做什么,我们可能会更容易提供帮助。具体来说,您是否只需要为每个学生打印一个“总分”?如果是这种情况,您不需要存储比当前学生更多的数据。如果您需要每个作业的整体班级“平均值”,您可能仍然不需要每个学生的数据,只需要一些运行总计。
-
您需要如何处理这些数据?看起来您要计算加权平均值。在这种情况下,您可以简单地一次读取一行,处理它,然后打印结果。这样,您就不必担心一次存储每个学生的成绩。
-
抱歉,我一直盯着这个看太久了,我忘记了我为什么要这样做:)。我需要为每个作业和整体模块标记输出学生人数以及平均值和标准差。我还被指示使用结构数组
-
如果只需要输出每个学生的分数或成绩,则不必将信息保存在内存中。如果您必须按成绩顺序(或分数顺序)输出学生,那么您确实需要将它们全部保存在内存中。请记住,您可以将动态内存分配与
malloc()和realloc()一起使用,或者您可以简单地确定最大班级人数是某个人数(30、300、1000)学生并预先分配该最大人数,然后抱怨该人数是否超过(通过阅读文件的其余部分来说明最大值应该有多大是礼貌的)。 -
@Astabh - 我是新来的,但我认为可以编辑您的问题并添加更多信息。我更喜欢那个。将所有问题放在一个地方似乎更好,而不是必须阅读 cmets 才能发现整个问题。当他们更清楚所要求的内容时,它可能会鼓励其他人提供帮助。
标签: c