附上代码如下:
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//----文件(信息)读取-----------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
int File;
struct student*Tmp=First;
struct student*Tmp2;
//-----设置全局变量的中间变量----
//-----尝试从文件读取记录信息----
First=NULL;
if(!FileExists("StuScore.rcd")) //不存在这个文件
{
Application->MessageBoxA("没有找到成绩记录文件!","失败!",0);
return;
}
else
{
File=FileOpen("StuScore.rcd",fmOpenRead);
if(File==-1)
{
Application->MessageBoxA("打开文件记录失败!","失败!",0);
return;
}
while(true)
{
int hehe;
Tmp2=(struct student*)malloc(sizeof(struct student));
hehe=FileRead(File,Tmp2,sizeof(struct student));
if(hehe<sizeof(struct student))
{
free(Tmp2);
break; //文件读完了
}
if(!First) //First==NULL
{
First=Tmp2;
First->Next=First;
First->Pre=First;
Tmp=First;
}
else //First!=NULL
{
Tmp->Next=Tmp2;
Tmp->Next->Pre=Tmp;
Tmp=Tmp->Next;
Tmp->Next=First;
First->Pre=Tmp;
}
}
FileClose(File);
}
}
//---添加或修改------------------------------------------------------------------------
bool _fastcall TForm1::Add(bool RePlace)
{
//姓名和学号必须填好,成绩可以不填,
//并赋成绩为-1以标记没有登录成绩
if(EditNum->Text=="")
{
Application->MessageBoxA("请填写学生的学号!","错误输入!",0);
return false;
}
else if(EditName->Text=="")
{
Application->MessageBoxA("请填写学生的姓名!","错误输入!",0);
return false;
}
else if(!RBtnMale->Checked&&!RBtnFemale->Checked)
{
Application->MessageBoxA("请选择学生的性别!","错误输入!",0);
return false;
}
else
{
struct student*temp=(struct student*)malloc(sizeof(struct student));
//寻找对应id的姓名,如果链表中存在id;
//则不添加用户
struct student*temp2=First;
if(First&&!RePlace)//连表不为空,并且是新增信息,不是修改
{
do
{
if(EditNum->Text.ToInt()==temp2->ID) //ToInt()把里面的字符串转换成整数
{
//存在此ID
Application->MessageBoxA("此学号已存在,请更改!",
"错误输入!",0);
return false;
}
else
{
temp2=temp2->Next;
}
} while(temp2!=First); //遍历循环链表
}
//现在可以添加信息了
temp->ID=EditNum->Text.ToInt();
StrPCopy(temp->Name,EditName->Text);
//纪录性别
if(RBtnMale->Checked) temp->Sex=0; //男
else temp->Sex=1; //女
//记录成绩
if(EditMath->Text=="") temp->Math=-1; //不登记成绩
else temp->Math=EditMath->Text.ToDouble();
if(EditChinese->Text=="") temp->Chinese=-1;
else temp->Chinese=EditChinese->Text.ToDouble();
if(EditEnglish->Text=="") temp->English=-1;
else temp->English=EditEnglish->Text.ToDouble();
//把temp加入链表中
if(!First) //没有记录
{
First=temp;
First->Next=First;
First->Pre=First;
}
else
{
temp->Pre=First->Pre;
temp->Next=First;
temp->Pre->Next=temp;
temp->Next->Pre=temp;
}
}
return true;
}
//---删除-------------------------------------------------------------------------
void _fastcall TForm1::Del(struct student* DelStu)
{
if(DelStu&&First) //链表中存在学生信息,而且要删除的信息不为空
{
if(First==DelStu) //删除第一条信息
{
if(First->Next==First)//只有一条信息
First=NULL;
else
First=First->Next;
}
DelStu->Pre->Next=DelStu->Next;
DelStu->Next->Pre=DelStu->Pre;
free(DelStu);
}
}
//-----信息的查找(onchange事件的响应)---------------------------------------------------------------
void __fastcall TForm1::EditNumChange(TObject *Sender)
{
//寻找对应id的姓名,如果在链表中存在id,
//如果处在编辑状态,即新添信息,或者修改信息,那么不处理此事件
if(EditName->Enabled) return;
//TmpStu是全部变量,它要对应当前在窗口中显示的信息
//所以,每次的EditNum改变,都要先清空它
TmpStu=NULL;
EditName->Text="";
RBtnMale->Checked=false;
RBtnFemale->Checked=false;
EditMath->Text="";
EditChinese->Text="";
EditEnglish->Text="";
if(!First) return; //还没有任何的学生信息,则直接返回
//在查找,更改(查找要更改的信息),删除(查找要删除的信息)
//都要根据学号的变化适时显示信息,这个功能由这段代码实现
struct student*NowTmp=First;
//查找对应学号的信息,并用全局变量TmpStu来指向它
if(EditNum->Text.Length()) //学号输入框不为空
{
do
{
if(EditNum->Text.ToInt()==NowTmp->ID)
{ //找到信息,显示在窗体中
TmpStu=NowTmp;
EditName->Text=TmpStu->Name;
if(TmpStu->Sex) RBtnFemale->Checked=true;
else RBtnMale->Checked=true;
if(TmpStu->Math==-1) EditMath->Text=""; //未登记成绩
else EditMath->Text=TmpStu->Math;
if(TmpStu->Chinese==-1) EditChinese->Text="";
else EditChinese->Text=TmpStu->Chinese;
if(TmpStu->English==-1) EditEnglish->Text="";
else EditEnglish->Text=TmpStu->English;
//如果是在查找和删除模式下, 则把OK/Cancel按钮置为可用
if(TabSet1->TabIndex==2||TabSet1->TabIndex==3)
{
BitBtn1->Enabled=true;
BitBtn2->Enabled=true;
}
break; //找到信息后跳出while循环
}
else
{
NowTmp=NowTmp->Next; //下一个信息
}
} while(NowTmp!=First); // 遍历环形链表
}
}
//---------------------------------------------------------------------------
//---信息的保存------------------------------------------------------------------------
void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
{
Save(false); //自动保存
}
void _fastcall TForm1::Save(bool Auto)
{
int File;
struct student*Tmp=First;
if(!First) //没有用户信息
{
if(!Auto) Application->MessageBoxA("没有学生信息!","保存失败",0);
return ;
}
if(FileExists("StuScore.rcd")) //存在记录文件
{
if(!DeleteFile("StuScore.rcd")) //删除失败
{
Application->MessageBoxA("删除旧记录失败!","不能保存",0);
}
}
File=FileCreate("StuScore.rcd");
if(File==-1) //创建失败
{
Application->MessageBoxA("创建文件 StuScore.rcd 失败,不能保存","失败",0);
}
//写文件
do
{
if(FileWrite(File,Tmp,sizeof(struct student))==-1);
Application->MessageBoxA("一个错误!","提示",0);
Tmp=Tmp->Next;
} while(Tmp!=First);
FileClose(File);
}
//----TabSet的响应-----------------------------------------------------------------------
void __fastcall TForm1::TabSet1Change(TObject *Sender, int NewTab,
bool &AllowChange)
{ switch(TabSet1->TabIndex)
{
case 0: //添加新学生
{ //设置组建可用
EditName->Enabled=true;
GroupBoxSex->Enabled=true;
GroupBoxScore->Enabled=true;
BitBtn1->Enabled=true;
BitBtn2->Enabled=true;
LabelHint->Caption="提示:输入学生学号,其它信息随学号动态显示";
}
break;
case 2://修改
{
EditName->Enabled=false;
GroupBoxSex->Enabled=false;
GroupBoxScore->Enabled=false;
//在输入学号被查找到的时候,置按钮可用
BitBtn1->Enabled=false;
BitBtn2->Enabled=false;
LabelHint->Caption="提示:输入学号,点击OK,修改后按OK保存修改";
}
break;
case 3://删除
{
EditName->Enabled=false;
GroupBoxSex->Enabled=false;
GroupBoxScore->Enabled=false;
//在输入学号被查找到的时候,置按钮为可用
BitBtn1->Enabled=false;
BitBtn2->Enabled=false;
LabelHint->Caption="提示:输入学号,点击OK完成删除";
}
break;
case 4:
{
Close();
}
break;
default: break;
}
//每次更改状态,都要清空各个组件的内容
EditNum->Text="";
EditName->Text="";
RBtnFemale->Checked=false;
RBtnMale->Checked=false;
EditMath->Text="";
EditChinese->Text="";
EditEnglish->Text="";
}
//-----------------------------------------------------------------------
//----Cancel-----------------------------------------------------------------------
void __fastcall TForm1::BitBtn2Click(TObject *Sender)
{
TabSet1->OnClick(this);
}
//-----"OK"----------------------------------------------------------------------
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
switch(TabSet1->TabIndex)
{
case 0: //添加新生
{
if(Add(false)) //添加成功
{
TabSet1->TabIndex=0;
TabSet1->OnClick(this);
}
else //添加失败
{};
}
break;
case 1: break; //查找不会有这种情况
case 2: //更改
{
if(!EditName->Enabled) //还没找到要修改的信息
{ //设当前的学生信息为要修改的学生信息
//各个组件设为可用,以供修改信息
EditName->Enabled=true;
GroupBoxSex->Enabled=true;
GroupBoxScore->Enabled=true;
}
else //已经修改,现在确认修改
{ //修改完毕,将各个组件中的信息写入全局中间变量TmStu中
if(Add(true))//加入信息成功
{
Del(TmpStu); //删除TmStu指向的需要修改的信息
TmpStu=NULL;
TabSet1->TabIndex=2;
TabSet1->OnClick(this);
}
else //输入的新信息不合法
{
//不作处理,等待更改后再接按OK
}
}
}
break;
case 3: //删除
{
Del(TmpStu); //删除当前的学生信息
TmpStu=NULL;
TabSet1->TabIndex=3;
TabSet1->OnClick(this);
}
break;
case 4: break; //不会有这种情况
default: break;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
}
//---------------------------------------------------------------------------
```问题如下
1: 在运行的时候,TabSet1Change函数已经设置了相应的组件可用,TabIndex为添加的时候,为什么要点击好几次才能输入名字Edit等,而且奇怪的是数学成绩Edit一直不能输入,而语文和英语可以输入。
输入完成的时候,问题又来了,显示如下图

问题很多,希望高手们提出来,本人刚接触Builder,我会及时采纳,或者有学生成绩管理的c++ builder可以参考的,也可以发出来,谢谢。