主要代码如下,其余的小工具无关重要:
程序代码:
/*
http://bbs.bccn.net/thread-439538-1-1.html
题目:学生成绩统计 (一维数组) 从键盘输入一个班(全班最多不超过 30人)学生某门课的成绩, 当输入成绩为负值时, 输入结束, 分别
实现下列功能:(1)统计不及格人数并打印不及格学生名单;(2)统计成绩在全班平均分及平均分之上的学生人数, 并打印这些学生的名单;
(3)以直方图方式统计各分数段的学生人数及所占的百分比。
形式如下:分段 人数 图形
<60 3(10%)***
60‐69 8(…) ********
70‐79 7(…) *******
80‐89 8(…) ********
>=90 4(…) ***
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
// 学生信息结构
struct Student_Info
{
int ID; // 学号
char Name[20]; // 姓名(最多19个字符)
double Score; // 成绩
int Grade; // 等级
};
// 统计项结构
struct Statistics_Item
{
double low; // 统计段下限
double high; // 统计段上限
size_t count; // 人数
double percentage; // 百分比
};
// 全局数据
Student_Info Students[30]; // 学生数组(最多不超过30人)
const double Qualify_Value = 60.0; // 成绩合格线
Statistics_Item Statistics_Data[] = // 统计结果数组
{
{ 0.0, 59.0, 0, 0.0 },
{ 60.0, 69.0, 0, 0.0 },
{ 70.0, 79.0, 0, 0.0 },
{ 80.0, 89.0, 0, 0.0 },
{ 90.0, 100.0, 0, 0.0 }
};
// 函数原型
void Show_StudentInfo(Student_Info student); // 输出单个学生的明细信息
void List_Students(void); // 输出所有学生的明细资料
void Input_Data(const char* fileName); // 输入学生数据
double Get_Average(void); // 求取平均成绩
size_t Statistics_Unqualified(void); // 统计不合格学生人数并输出相关学生信息
void Statistics_GoodStudents(double average); // 统计在平均成绩以上的学生
void Statistics(void); // 统计
// 程序主入口
int main(int argc, char* argv[])
{
// 输入学生数据,如果有命令行参数,则从文本文件读入数据,否则从键盘输入
Input_Data((argc > 1) ? argv[1] : NULL);
List_Students();
putchar('\n');
Statistics_Unqualified();
putchar('\n');
Statistics_GoodStudents(Get_Average());
putchar('\n');
Statistics();
Pause("\n按任意键继续...");
return EXIT_SUCCESS;
}
void Show_StudentInfo(Student_Info student)
{
printf_s("%4u %-20s %6.2f %-4d\n", student.ID, student.Name, student.Score, student.Grade);
}
void List_Students(void)
{
printf_s("%4s %-20s %6s %4s\n", "学号", "姓名", "成绩", "等级");
// 注:_countof()是宏,计算静态分配的数组的元素个数,在stdlib.h头中定义
for (size_t index = 0; (index < _countof(Students)) && (Students[index].Score >= 0); ++index)
{
Show_StudentInfo(Students[index]);
}
}
void Input_Data(const char* fileName)
{
FILE* file = stdin;
if (fileName != NULL)
{
errno_t errorCode = fopen_s(&file, fileName, "rt");
if (errorCode != 0)
{
file = stdin;
}
}
for (size_t index = 0; index < _countof(Students); ++index)
{
if (file == stdin)
{
// 从键盘输入数据
printf_s("请输入第%2u个学生的数据(成绩为负数结束):\n", index + 1);
do
{
printf_s("学号: ");
fflush(stdin);
} while(scanf_s("%d", &Students[index].ID) == 0);
do
{
printf_s("姓名: ");
fflush(stdin);
} while(gets_s(Students[index].Name, _countof(Students[index].Name) - 1) == NULL);
do
{
printf_s("成绩: ");
fflush(stdin);
} while(scanf_s("%lf", &Students[index].Score) == 0);
if (Students[index].Score < 0)
{
// 当输入的成绩为负数时结束输入
Students[index].ID = 0;
Students[index].Name[0] = '\0';
break;
}
putchar('\n');
}
else
{
// 从文本文件读入数据
if ((fscanf_s(file, "%d %20s %lf", &Students[index].ID, Students[index].Name, 20, &Students[index].Score) != 3) || (Students[index].Score < 0))
{
Students[index].ID = 0;
Students[index].Name[0] = '\0';
break;
}
}
}
if (file != stdin)
{
fclose(file);
}
}
size_t Statistics_Unqualified(void)
{
size_t count = 0;
printf_s("不合格学生:\n");
for (size_t index = 0; (index < _countof(Students)) && (Students[index].Score >= 0); ++index)
{
if (Students[index].Score < Qualify_Value)
{
if (count == 0)
{
printf_s("%4s %-20s %6s %4s\n", "学号", "姓名", "成绩", "等级");
}
++count;
Show_StudentInfo(Students[index]);
}
}
printf_s("人数 = %u\n", count);
return count;
}
double Get_Average(void)
{
double sum = 0.0;
size_t number = 0;
for (size_t index = 0; (index < _countof(Students)) && (Students[index].Score >= 0); ++index)
{
sum += Students[index].Score;
++number;
}
return sum / number;
}
void Statistics_GoodStudents(double average)
{
size_t count = 0;
printf_s("成绩在平均分(%6.2f)以上的学生:\n", average);
for (size_t index = 0; (index < _countof(Students)) && (Students[index].Score >= 0); ++index)
{
if (Students[index].Score >= average)
{
if (count == 0)
{
printf_s("%4s %-20s %6s %4s\n", "学号", "姓名", "成绩", "等级");
}
++count;
Show_StudentInfo(Students[index]);
}
}
printf_s("人数 = %u\n", count);
}
void Statistics(void)
{
size_t total = 0;
for (size_t i = 0; (i < _countof(Students)) && (Students[i].Score >= 0); ++i)
{
++total;
for (size_t j = 0; j < _countof(Statistics_Data); ++j)
{
if ((Students[i].Score >= Statistics_Data[j].low) && (Students[i].Score <= Statistics_Data[j].high))
{
++Statistics_Data[j].count;
}
}
}
printf_s("%15s %4s 图形\n", "分数", "人数");
for (size_t i = 0; i < _countof(Statistics_Data); ++i)
{
printf_s("%6.2f - %6.2f %4u ", Statistics_Data[i].low, Statistics_Data[i].high, Statistics_Data[i].count);
for (size_t j = 0; j < Statistics_Data[i].count; ++j)
{
putchar('*');
}
putchar('\n');
}
}