数模论坛

 找回密码
 注-册-帐-号
搜索
热搜: 活动 交友 discuz
查看: 2574|回复: 1

简易选课管理,(大二的习题)

[复制链接]
发表于 2004-5-7 18:47:06 | 显示全部楼层 |阅读模式
<FONT size=3>写的不好,当时竟忘了用结构体,BEN!

好象现在大二的同学也正在做这道题,程序中有少量注释,感兴趣的同学我们可以再讨论
//*************************************************************************************
//      
//                 功能:  根据输入的学生、课程和选课信息,建立简易网状数据库系统
//       作者:  吴志坚
//       时间:  02年3月17日
//
//
//                 **对三个数据表各字段的说明:**
//
//                        **学生表(学号,姓名,班级&lt;系&gt;,指向的表,对应表中的位置)**
//                        **成绩表(成绩&lt;等级&gt;,指向下一成绩的指针,该指针的尾,指向课程的指针)**
//                        **课程表(课号,课名,学分,指向学生的指针,指针的尾)**
//
//
//**************************************************************************************

#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;fstream&gt;
#include &lt;iomanip&gt;
#include &lt;cctype&gt;

using namespace std;

//参数修改
const int STU_MAX = 20;                //学生文件中最大学生数
const int COR_MAX = 20;                //课程文件中最大课程数
const int MAX_PER = 3 ;                //每个人最多报课数
const string STU_FILE = "stuFile.txt";                //学生信息文件
const string COR_FILE = "corFile.txt";                //课程信息文件
const string SCORE_FILE = "score.txt";                //成绩信息文件

//勿修改
const string README = "readme.txt";

        //学生信息
        string stuNo[ STU_MAX ];
        string stuName[ STU_MAX ];
        string stuClass[ STU_MAX ];
        string stuPt[ STU_MAX ];
        int stuPtRear[ STU_MAX ];//完整的指针为stuPt+ptRear

        //成绩信息
        string score[ STU_MAX * MAX_PER ];
        string ptNextScore[ STU_MAX * MAX_PER ];
        int ptNextScoreRear[ STU_MAX * MAX_PER ];
        int ptCourse[ STU_MAX * MAX_PER ];
        //int ptNextSame[ STU_MAX * MAX_PER ];

        //课程信息
        string corNo[ COR_MAX ];
        string corName[ COR_MAX ];
        string credit[ COR_MAX ];
        string corPt[ COR_MAX ];
        int corPtRear[ COR_MAX ];

char Menu( )
//显示菜单函数
{
        const string BLANK_LENGTH="  ";
        char choice;
        cout &lt;&lt; endl
                 &lt;&lt; BLANK_LENGTH
                 &lt;&lt; "S)创建初始学生文件" &lt;&lt; endl
                 &lt;&lt;        BLANK_LENGTH
                 &lt;&lt; "C)创建初始课程文件" &lt;&lt; endl
                 &lt;&lt; BLANK_LENGTH
                 &lt;&lt; "I)输入选课情况" &lt;&lt; endl
                 &lt;&lt; BLANK_LENGTH
                 &lt;&lt; ")学生查询" &lt;&lt; endl
                 &lt;&lt; BLANK_LENGTH
                 &lt;&lt; "T)教师查询" &lt;&lt; endl
                 &lt;&lt; BLANK_LENGTH
                 &lt;&lt; "H)使用手册" &lt;&lt; endl
                 &lt;&lt; BLANK_LENGTH
                 &lt;&lt; "X)退出" &lt;&lt; endl;
        cin &gt;&gt; choice;
        return choice;
}

bool IsInputRight( )
//询问输入是否正确函数
{
        while( 1 )
        {
                cout &lt;&lt; "以上输入是否正确?( Y/N )";
                char isRight = ' ';
                cin &gt;&gt; isRight;
                if( toupper(isRight) == 'Y' || toupper(isRight) == 'N' )
                {
                        if( toupper(isRight) == 'Y')  return true ;
                        else { cout &lt;&lt; "请重新输入以上信息" &lt;&lt; endl ; return false ; }
                }
        }
}

bool Output2File( const string FILE_NAME, int mesNum, string mes1[ STU_MAX ], string mes2[ STU_MAX ], string mes3[ STU_MAX ] )
//将信息写入文件
{
        ofstream outFile;
        outFile.open(FILE_NAME.c_str() );
        if( !outFile )  return false ;
        string ptFile = "scoreFile.txt 0" ; //初始化的指针域
        for( int j = 0; j &lt; mesNum; j++ )
        {
                outFile &lt;&lt; mes1[j] &lt;&lt; " " &lt;&lt; mes2[j] &lt;&lt; " " &lt;&lt; mes3[j] &lt;&lt; " " &lt;&lt;  ptFile &lt;&lt; endl;
        }
        return true;
}
bool InitFile( const int MAX_VALUE, const string FILE_NAME )
//初始化学生、课程信息文件
{
        int messageNum;//当前信息数目
        string message1Temp[STU_MAX];//除了指针域外的三条信息
        string message2Temp[STU_MAX];
        string message3Temp[STU_MAX];

        string format = " \"学号 姓名 系别\" ";
        if( FILE_NAME == COR_FILE )        format = " \"课号 课名 学分\" ";
        while( 1 )
        {        
                cout &lt;&lt; "请按照" + format + "的格式输入信息(最多" &lt;&lt; MAX_VALUE &lt;&lt; "条), 输入完毕请按\"X\" "
                     &lt;&lt; endl;
                messageNum = 0;
                string temp;
                int isEndCin = false;
                while( 1 )
                {
                        cin &gt;&gt; temp;
                        if( temp != "X" &amp;&amp; temp != "x" )
                        {
                                message1Temp[ messageNum ] = temp; //C++允许这种赋值方式
                                cin &gt;&gt; message2Temp[ messageNum ] &gt;&gt; message3Temp[ messageNum ];
                        }
                        else break; //提前退出
                        messageNum++;
                        if ( messageNum &gt;= MAX_VALUE ) {        cout &lt;&lt; MAX_VALUE &lt;&lt; "条信息已输入完毕~" &lt;&lt; endl; break;        }//超过最大记录数而退出                        
                }
                if( isEndCin = IsInputRight( ) ) break; //输入完毕且确认无误后退出输入
        }

        //将正确信息写入相应文件
        if( !Output2File(  FILE_NAME, messageNum, message1Temp, message2Temp, message3Temp ) ) return false;
        return true;
}
bool SletCor( )
//先将所有数据放在若干临时数组中,待全部录入完毕后再用指针一一连接,读入文件中
{
        string stuNoTemp[ STU_MAX * MAX_PER ] ;//临时记录学号
        string corNoTemp[ STU_MAX * MAX_PER ] ;//临时记录课号
        //string score[ STU_MAX * MAX_PER ] ;//临时记录成绩
        
        int scoreSize;//成绩信息条数
        while( 1 )
        {        
                cout &lt;&lt; "请按照\" 学号 课号 成绩 \"的格式输入选课信息(每人不得超过" &lt;&lt; MAX_PER &lt;&lt; "门), 输入完毕请按\"X\" "
                     &lt;&lt; endl;
                scoreSize = 0;
                string temp;
                int isEndCin = false;
                while( 1 )
                {
                        cin &gt;&gt; temp;
                        if( temp != "X" &amp;&amp; temp != "x" )
                        {
                                stuNoTemp[ scoreSize ] = temp;
                                cin &gt;&gt; corNoTemp[ scoreSize ] &gt;&gt; score[ scoreSize ];
                        }
                        else break; //提前退出
                        scoreSize++;
                        if ( scoreSize &gt;= STU_MAX * MAX_PER ) {        cout &lt;&lt; STU_MAX * MAX_PER &lt;&lt; "条信息已输入完毕~" &lt;&lt; endl; break; }//超过最大记录数而退出                        
                }               
                if( isEndCin = IsInputRight() ) break; //输入完毕且确认无误后退出输入
        }
               
        //将文件中的数据读入内存
        ifstream inStuFile;
        inStuFile.open( STU_FILE.c_str() );
        int j = 0;
        while( inStuFile &gt;&gt; stuNo[ j ] )
        {
                inStuFile &gt;&gt; stuName[ j ];
                inStuFile &gt;&gt; stuClass[ j ];
                inStuFile &gt;&gt; stuPt[ j ] ;
                inStuFile &gt;&gt; stuPtRear[ j ];
                j++;
        }
        int studentSize = j ;//学生实际人数
        ifstream inCorFile;
        inCorFile.open( COR_FILE.c_str() );
        j = 0;
        string unused;
        while( inCorFile &gt;&gt; corNo[ j ] )  {
                inCorFile &gt;&gt;  unused &gt;&gt; unused &gt;&gt; corPt[ j++ ] &gt;&gt; unused ;
        }
        int courseSize = j ;//课程实际数目

        //数据处理,连结指针
        for( j = 0; j &lt; scoreSize; j++ )
        {
                static string lastStuNo = "";
                //学生与成绩的连结
                if( stuNoTemp[ j ] != lastStuNo )
                {//不相等说明这是第一次出现
                        for( int k = 0 ; k &lt; studentSize; k++ )
                        {        if( stuNo[ k ] == stuNoTemp[ j ] ) break;        }
                        stuPtRear[ k ] = j;
                }
                else
                {
                        ptNextScore[ j-1 ] = SCORE_FILE;
                        ptNextScoreRear[ j-1 ] = j;
                        //ptNextScore[ j ] = "TAIL";//指针末端
                        //ptNextScoreRear[ j ] = NULL;               
                }
                ptNextScore[ j ] = "TAIL";//指针末端
                ptNextScoreRear[ j ] = NULL;
                lastStuNo = stuNoTemp[ j ];
                //成绩与课程指针的连结
                for( int index = 0 ; index &lt; courseSize ; index++ )
                {
                        if( corNoTemp[ j ] == corNo[ index ] )
                        {        ptCourse[ j ] = index;        break;        }
                }        
        }</FONT>
 楼主| 发表于 2004-5-7 18:47:30 | 显示全部楼层
<FONT size=3>   //将更新后的学生文件写入新文件
        ofstream out2NewStuF( STU_FILE.c_str() ) ;
        for( j = 0; j &lt; studentSize; j++ )
        {
                out2NewStuF &lt;&lt; stuNo[ j ] &lt;&lt; " " &lt;&lt; stuName[ j ] &lt;&lt; " " &lt;&lt; stuClass[ j ] &lt;&lt; " "
                                    &lt;&lt; stuPt[ j ] &lt;&lt; " " &lt;&lt; stuPtRear[ j ] &lt;&lt; endl;
        }
        out2NewStuF.close( ) ;
        //将成绩信息写入文件SCORE_FILE中
        ofstream out2ScoreF( SCORE_FILE.c_str() ) ;
        for( j = 0; j &lt; scoreSize; j++ )
        {
                out2ScoreF &lt;&lt; score[ j ] &lt;&lt; " " &lt;&lt; ptNextScore[ j ] &lt;&lt; " " &lt;&lt; ptNextScoreRear[ j ] &lt;&lt; " "
                                   &lt;&lt; ptCourse[ j ] &lt;&lt; endl;
        }
        out2ScoreF.close( ) ;
        
        return true;
}
bool SearchStu( )
//根据学号查询学生
{
        //将文件中的数据读入内存
        ifstream inStuFile;
        inStuFile.open( STU_FILE.c_str() );
        int j = 0;
        while( inStuFile &gt;&gt; stuNo[ j ] ) {
                inStuFile &gt;&gt; stuName[ j ] &gt;&gt; stuClass[ j ] &gt;&gt; stuPt[ j ] &gt;&gt; stuPtRear[ j ] ;
                j++;
        }
        int studentSize = j ;//学生实际人数
        ifstream inCorFile;
        inCorFile.open( COR_FILE.c_str() );
        j = 0;
        while( inCorFile &gt;&gt; corNo[ j ] )  {
                inCorFile &gt;&gt; corName[ j ]  &gt;&gt; credit[ j ] &gt;&gt; corPt[ j ] &gt;&gt; corPtRear[ j ] ;
                j++;
        }
        int courseSize = j ;//课程实际数目
        ifstream inScoFile;
        inScoFile.open( SCORE_FILE.c_str() );
        j = 0 ;
        while( inScoFile &gt;&gt; score[ j ] ){
                inScoFile &gt;&gt; ptNextScore[ j ] &gt;&gt; ptNextScoreRear[ j ] &gt;&gt; ptCourse[ j ] ;
                j++;
        }
        int scoreSize = j ; //成绩实际条数

        string stuNoSeah ;
        cout &lt;&lt; "请输入学号: " ;
        cin &gt;&gt; stuNoSeah ;
        int FindPosF( string , int );
        int posInStuF;
        if( ( posInStuF = FindPosF( stuNoSeah, studentSize ) ) == STU_MAX+1 )        
                return false;
        void PrtRecordCard( int );
        PrtRecordCard( posInStuF );
        return true;
}

void PrtRecordCard( int posInStuF )
//打印学生成绩单函数
{
        /*for(int i=0 ; i&lt;4 ; i++)
        {
                cout &lt;&lt; score &lt;&lt; ptNextScore &lt;&lt; ptNextScoreRear &lt;&lt; ptCourse &lt;&lt; endl;
        }
        */
        //cout &lt;&lt; ptNextScore[4] &lt;&lt; endl;
        
        string prtStuNo = stuNo[ posInStuF ];//"prt"为欲打印的标记
        string prtStuName = stuName[ posInStuF ];
        string prtStuClass = stuClass[ posInStuF ];
        //string prtStuPt = stuPt[ posInStuF ];
        int posInScoF = stuPtRear[ posInStuF ];
        string prtSco[ MAX_PER ] ;
        string prtCorNo[ MAX_PER ] ;
        string prtCorName[ MAX_PER ] ;
        string prtCredit[ MAX_PER ] ;  
        int j = 0 ;
        int posInCorF;
        do{
                prtSco[ j ] = score[ posInScoF ];
                posInCorF = ptCourse[ posInScoF ];
                prtCorNo[ j ] = corNo[ posInCorF ];  
                prtCorName[ j ] = corName[ posInCorF ];
                prtCredit[ j ] = credit[ posInCorF ];
                j++;
        }while( ptNextScore[ posInScoF++ ] != "TAIL"  );
        
        //打印成绩单
        cout &lt;&lt; endl;
        cout &lt;&lt; "姓名 "&lt;&lt; prtStuName &lt;&lt; endl
                 &lt;&lt; "学号 "&lt;&lt; prtStuNo &lt;&lt; endl
                 &lt;&lt; "班级 "&lt;&lt; prtStuClass &lt;&lt; endl
                 &lt;&lt; " 课号 " &lt;&lt; "  科       目  " &lt;&lt; " 成绩 " &lt;&lt; endl;
        for( int k = 0 ; k &lt; j; k++ )
        {
                cout &lt;&lt; setw(4) &lt;&lt; prtCorNo[ k ] &lt;&lt; setw(10) &lt;&lt;prtCorName[ k ]
                         &lt;&lt; setw(5) &lt;&lt; "(" + prtCredit[ k ] + ")"
                         &lt;&lt; setw(5) &lt;&lt;prtSco[ k ] &lt;&lt; endl;
        }
        cout &lt;&lt; endl;
}

int FindPosF( string stuNoSeah, int studentSize )
{
        for( int pos = 0; pos &lt; studentSize; pos++ )
                if( stuNoSeah == stuNo[ pos ] )                return pos;
        return STU_MAX+1;
}
void PrintForTeac( int order, int studentSize, int scoreSize )
//打印选修课的情况(教师使用)
{
        int pos,tem;
        cout &lt;&lt; endl &lt;&lt; corName[order] &lt;&lt; "选课情况:" &lt;&lt; endl;
        cout &lt;&lt; "  学 号  " &lt;&lt; "  姓 名  " &lt;&lt; "  专 业  " &lt;&lt; endl;
        for( int i=0; i&lt;studentSize; i++ )
        {
                pos=stuPtRear;
                do{
                        if( ptCourse[ pos ] == order )
                                cout &lt;&lt; setw(7) &lt;&lt;stuNo &lt;&lt;  setw(9) &lt;&lt; stuName &lt;&lt; setw(9) &lt;&lt; stuClass &lt;&lt; endl;
                        tem=pos;
                        pos=ptNextScoreRear[ pos ];
                }while(ptNextScoreRear[tem]!=0);
        }
}

bool TeacherSear()
{
        //将文件中的数据读入内存
        ifstream inStuFile;
        inStuFile.open( STU_FILE.c_str() );
        int j = 0;
        while( inStuFile &gt;&gt; stuNo[ j ] ) {
                inStuFile &gt;&gt; stuName[ j ] &gt;&gt; stuClass[ j ] &gt;&gt; stuPt[ j ] &gt;&gt; stuPtRear[ j ] ;
                j++;
        }
        int studentSize = j ;//学生实际人数
        ifstream inCorFile;
        inCorFile.open( COR_FILE.c_str() );
        j = 0;
        while( inCorFile &gt;&gt; corNo[ j ] )  {
                inCorFile &gt;&gt; corName[ j ]  &gt;&gt; credit[ j ] &gt;&gt; corPt[ j ] &gt;&gt; corPtRear[ j ] ;
                j++;
        }
        int courseSize = j ;//课程实际数目
        ifstream inScoFile;
        inScoFile.open( SCORE_FILE.c_str() );
        j = 0 ;
        while( inScoFile &gt;&gt; score[ j ] ){
                inScoFile &gt;&gt; ptNextScore[ j ] &gt;&gt; ptNextScoreRear[ j ] &gt;&gt; ptCourse[ j ] ;
                j++;
        }
        int scoreSize = j ; //成绩实际条数

        string stuNoSeah ;
        cout &lt;&lt; "请输入课号: " ;
        string courseID;
        cin &gt;&gt; courseID;
        for( j=0; j&lt; courseSize; j++ )
                if( courseID==corNo[j] )        break;
        if( j == courseSize )        return false;
        PrintForTeac( j, studentSize, scoreSize );
        return true;
}

void ReadMe(const string README )
{
        string content;
        ifstream inFile;
        inFile.open( ( README.c_str() ) );
        while ( getline( inFile, content) )//读入文件中的一行
                cout &lt;&lt; content &lt;&lt; endl;
}

void main( )
{
        //函数声明
    char Menu( );//菜单打印函数
        bool InitFile( const int, const string );//初始化学生文件或课程文件函数
        bool SletCor( );//输入选课情况
        bool IsInputRight( );//检查输入是否正确
        bool SearchStu( );//学生查询函数
        int FindPosF( string, int );//查询记录在文件中的位置
        void PrtReportCard( int );//打印学生成绩单
        bool TeacherSear();
        void PrintForTeac( int, int, int);//打印选修课的情况(教师使用)

        char choiceMenu;
        int isBrkPgm = false ;//标志是否退出整个程序

        while( !isBrkPgm )
        {
                switch( choiceMenu = toupper( Menu() ) )
                {
                case 'S' : if( !InitFile( STU_MAX, STU_FILE ) ) cerr &lt;&lt; "Cannot execute the function normally!" &lt;&lt; endl; break;
                case 'C' : if( !InitFile( COR_MAX, COR_FILE ) ) cerr &lt;&lt; "Cannot execute the function normally!" &lt;&lt; endl; break;
                case 'I' : if( !SletCor( ) ) cerr &lt;&lt; "Cannot execute the function normally!\n" ; break ;
                case 'P' : if( !SearchStu( ) ) cerr &lt;&lt; "不存在该学号\a\n" ; break ;
                case 'H' : ReadMe( README ) ; break ;
                case 'T' : if( !TeacherSear( ) ) cerr &lt;&lt; "不存在该课号\a\n" ; break;
                case 'X' : isBrkPgm = true ; break ;
                default  : isBrkPgm = false ;
                }                           
        }
}


另外,还须在同层下建立四个文件(均已在程序头部说明)
这个程序有一点不足(当然有很多BUG)就是同个学生的数据须一次输完,
其实这个不足完全可以弥补,先任意输入各个学生的数据,再用一个排序函数将同一学生的数据靠在一块就解决了。</FONT>

您需要登录后才可以回帖 登录 | 注-册-帐-号

本版积分规则

小黑屋|手机版|Archiver|数学建模网 ( 湘ICP备11011602号 )

GMT+8, 2024-11-27 10:36 , Processed in 0.054907 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表