C 语言课程设计:SimpleCG打造实用学生信息管理(一)
上回我们已经完成了这个学生信息管理系统的一些基础功能,这篇继续完善上次的C课程设计,设计一个实用的学生信息管理系统。
一、分数录入功能
在前篇文章中,已经实现了成绩录入功能,只需要进入录入界面录入成绩后保存,就可以保存每科所有同学的成绩。从而为后续所有统计提供分数数据。
选择分数录入界面后,双击每个同学的分数栏就可以输入每个同学的分数,同时左侧按纽将变成保存成绩,点击就保存录入结果。这个录入效果是使用了SimpleGUI的一个列表控件实现。列表控件创建如下:
void CreateTableScore()
{
tagSG_Box rt={180,100,C_IMAGE_WIDTH-rt.left-2,C_IMAGE_HEIGHT-rt.top-2};
g_hFrame[enumTABLE_SCORE]=create_ListTableOwnerDrawEdit(NULL,RGB(0xAA,0xFF,0xAA),enumLISTTABLE_EXAM,&rt,6,DrawListTable, SetScoreText, GetScoreText);
ListTable_SetHeadTitle( g_hFrame[enumTABLE_SCORE], 0, _T("分数ID") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_SCORE], 1, _T("科目名") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_SCORE], 2, _T("科目批次") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_SCORE], 3, _T("学号") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_SCORE], 4, _T("姓名") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_SCORE], 5, _T("分数") );
ListTableOwnerDraw_SetItemCount(g_hFrame[enumTABLE_SCORE], GetExamCnt());
ListTableOwnerDraw_SetPageSize(g_hFrame[enumTABLE_SCORE], (650-30)/25);
}
其中SetScoreText, GetScoreText两个函数定义了分数录入的功能。
bool SetScoreText(HSCGTREEID hObjectID, int nLine, int nColumnIndex, const TCHAR *pText )
{
float fSetValue = 0.0f;
tagScore* pScore = GetScoreByIndex(nLine);
if(NULL!=pScore)
{
switch(nColumnIndex)
{
case 5:
fSetValue = ( float )_tcstod( pText, NULL );
if(fSetValue>=0 && fSetValue<=100)
{
pScore->fScore = fSetValue;
return true;
}
else
{
MessageBox(g_hWnd,_T("分数必须介于0到100"),_T(""),MB_OK);
return false;
}
break;
default:
break;
}
}
return false;
}
bool GetScoreText(HSCGTREEID hObjectID, int nLine, int nColumnIndex, TCHAR *pText, int nSize )
{
tagScore* pScore = GetScoreByIndex(nLine);
if(NULL!=pScore)
{
switch(nColumnIndex)
{
case 5:
_stprintf_s( pText, nSize, _T("%0.2f"), pScore->fScore);
return true;
break;
default:
break;
}
}
return false;
}
二、添加分数统计功能
1、单学科分单元统计
我们前面的科目表里已经附带了科目的批次单元字段,所以我们的系统不仅可以分科目保存分数,同一科目还可以分学年和分单元记录,所以先实现最简单的特定科目特定单元的统计功能。
例如上图中,语文科目有期中考和单元测验两组分数,我们选中语文单元一,选择特定科目统计。就出现如下统计结果:
已经按分数排好了倒序。
科目单元统计功能代码如下:
//统计某科特定单元考试
void OnStatusExamBatchResult()
{
int nSel = ListTable_GetCurSel(g_hFrame[enumTABLE_EXAM]);
if(nSel>=0)
{
TCHAR pTextMsg[LABEL_LEN_STRING];
tagExam* pExam = GetExamByIndex(nSel);
if( NULL != pExam)
{
tagScore* pScore = NULL;
TCHAR pFileScoreName[MAX_PATH]={0};
TCHAR pScoreName[MAX_PATH]={0};
int nGoodCnt = 0;
int nFaildCnt = 0;
int nCount = 0;
float fTotal = 0.0f;
_stprintf_s( pScoreName, MAX_PATH, _T("Score%d"), pExam->nID );
GetSubName( pFileScoreName, MAX_PATH, g_pFileName, pScoreName );
if(LoadFromeFileScore(pFileScoreName))
{
//冒泡排序法按分数从高到低排序
SortScore(false);
pScore = FirtScore();
}
if(NULL==pScore)
{
return;
}
SCGUI_EnableObject(g_hButton[enumBTN_EXAM_ADD],false);
SCGUI_EnableObject(g_hButton[enumBTN_EXAM_DEL],false);
SCGUI_EnableObject(g_hButton[enumBTN_EXAM_MODIFY],false);
SCGUI_EnableObject(g_hButton[enumBTN_EXAMRESULT_MODIFY],false);
ShowFrame(enumTABLE_SCORE_STATUS);
SCGUIComboBox_DeleteAll(g_hButton[enumBTN_EXAMRESULT_COMBO_BATCH]);
SCGUIComboBox_DeleteAll(g_hButton[enumBTN_EXAMRESULT_COMBO_EXAM]);
SCGUIComboBox_AddText( g_hButton[enumBTN_EXAMRESULT_COMBO_BATCH], pExam->strBatch );
SCGUIComboBox_AddText( g_hButton[enumBTN_EXAMRESULT_COMBO_EXAM], pExam->strName );
SCGUIComboBox_SetCurSel( g_hButton[enumBTN_EXAMRESULT_COMBO_BATCH], 0 );
SCGUIComboBox_SetCurSel( g_hButton[enumBTN_EXAMRESULT_COMBO_EXAM], 0 );
SCGUI_EnableObject(g_hButton[enumBTN_EXAMRESULT_COMBO_BATCH], false);
SCGUI_EnableObject(g_hButton[enumBTN_EXAMRESULT_COMBO_EXAM], false);
ListTable_SetHeadCount( g_nTable[enumSUBTABLE_SCORE_STATUS], 4 );
ListTable_SetHeadTitle( g_nTable[enumSUBTABLE_SCORE_STATUS], 0, _T("排名") );
ListTable_SetHeadTitle( g_nTable[enumSUBTABLE_SCORE_STATUS], 1, _T("学号") );
ListTable_SetHeadTitle( g_nTable[enumSUBTABLE_SCORE_STATUS], 2, _T("姓名") );
ListTable_SetHeadTitle( g_nTable[enumSUBTABLE_SCORE_STATUS], 3, _T("分数") );
SCGUIListTable_DeleteAll(g_nTable[enumSUBTABLE_SCORE_STATUS]);
{
int nItem = 0;
int nIndex = 0;
float fMin = 100;
while(pScore)
{
float fScore = pScore->fScore;
if( fScore>=pExam->fExcellentScore )
++nGoodCnt;
else if(fScore<pExam->fFaileScore )
++nFaildCnt;
if( fScore>0 )
++nCount;
if( fScore>pExam->fMax )
pExam->fMax = fScore;
if( fScore<fMin )
fMin = fScore;
fTotal += pScore->fScore;
++nIndex;
_stprintf_s( pTextMsg, LABEL_LEN_STRING, _T("%d"), nIndex );
nItem = SCGUIListTable_AddItemText(g_nTable[enumSUBTABLE_SCORE_STATUS],pTextMsg );
SCGUIListTable_SetItemText(g_nTable[enumSUBTABLE_SCORE_STATUS], nItem, 1, pScore->strStuID );
SCGUIListTable_SetItemText(g_nTable[enumSUBTABLE_SCORE_STATUS], nItem, 2, pScore->strStuName );
_stprintf_s( pTextMsg, LABEL_LEN_STRING, _T("%0.2f"), pScore->fScore );
SCGUIListTable_SetItemText(g_nTable[enumSUBTABLE_SCORE_STATUS], nItem, 3, pTextMsg );
pScore = NextScore( pScore );
}
pExam->nCount = nCount;
pExam->fMin = fMin;
if(nCount>0)
pExam->fAveScore = fTotal / nCount;
}
_stprintf_s( pTextMsg, LABEL_LEN_STRING, _T("总人数 %d 优秀 %d 不及格 %d 平均分 %0.2f 最高 %0.2f 最低 %0.2f "), pExam->nCount, nGoodCnt, nFaildCnt, pExam->fAveScore, pExam->fMax, pExam->fMin );
SCGUILabel_SetText( g_hButton[enumBTN_EXAMRESULT_MSGLABEL], pTextMsg);
}
}
}
而且为了方便组织代码,将所有统计代码放到了ScoreStatus.c,和ScoreStatus.h文件当中。
2、分科目统计各单元成绩
当需要统计某科目所有测验时可以使用科目统计各单元成绩。将会列出某一科目的所有成绩,并计算出每个同学的平均分,从而得到一个综合评价。显示效果如下
代码就不展示了,有兴趣的同学可以直接下载全部代码察看,前面也说明了统计代码都归总到了一个文件当中。
3、分批次统计所有科目
我们也可以按批次统计同一批次所有科目的成绩情况。例如统计期中考试每个同学的各科成绩及总分情况。可以使用分批次统计所有科目。效果如下:
以上就是所有成绩统计相关的内容了。可能还有很多需要完善的地方,同学们可以下载后继续完善,相信你能够实现出更加完美实用的学生信息管理系统,在c课程设计中脱颖而出。
三、 按学生姓名或学号进行查询的功能
最后我们实现题目要求的查询功能。因为使用的是链表,为了简便就没有使用二分查找,同学可以自行设计完善。此处直接遍历搜索。界面效果如下:
除了显示学生基本信息外,一并列出该名学生所有考试成绩。所以在进入该界面后将读取所有的分数数据以待查询。
tagExam* pExam = NULL;
ReleaseListScore();
pExam = FirtExam();
while(pExam)
{
tagScore* pScore = NULL;
TCHAR pFileScoreName[MAX_PATH]={0};
TCHAR pScoreName[MAX_PATH]={0};
_stprintf_s( pScoreName, MAX_PATH, _T("Score%d"), pExam->nID );
GetSubName( pFileScoreName, MAX_PATH, g_pFileName, pScoreName );
if(!LoadFromeFileScoreAndSort(pFileScoreName))
{
pExam = NextExam( pExam );
continue;
}
pExam = NextExam( pExam );
}
四、结语
以上就是图形界面的学生信息管理系统的所有内容。可以看到更改为图形界面后,代码的增加量相当可观。主要是界面切换代码,因为需要很多界面调整过程,所以增加了代码量。这是与控制台编程不一样的地方。控制台的显示主要涉及文本调整,在界面细节调整上不多,所以可以把重点放在逻辑和功能上。
建议在正在学习c语言的同学可以把这两篇文章先收藏,等学期末时大作业可以拿来参考,因为虽然做的是学生信息管理系统,但所有信息管理系统都相通的,只是数据的处理与表示有所区别而已。当然还有很多需要完善的地方及可以增加的功能(例如图形分布、柱状图等),有兴趣的图学可以尝试添加。