String类,JudgePaper类

Posted on 2020-07-07 12:01  金色的省略号  阅读(202)  评论(0编辑  收藏  举报

  1、String类

#include <iostream>
#include <string.h>

/* String 类 */
class String{
    char* str;
public:
    String();
    String(const char* s);
    String(String&s);
    ~String();
    const char* getStr() const;
    String& operator = (const char* s);
    String& operator = (const String &s);
    friend std::ostream& operator <<(std::ostream& o, const String &s);
};

/*无参构造*/
String::String():str(NULL){}

/*参数字符串构造*/
String::String(const char* s){
    str = new char[strlen(s) + 1];
    strcpy(str,s);
}

/*拷贝构造*/
String::String(String &s){
    str = new char[strlen(s.str) + 1];
    strcpy(str,s.str);
}

/*析构*/
String::~String(){
    if(str) delete str;
}

/*返回对象的数据成员str*/
const char* String::getStr() const{
    return str;
}

/*重载 = 对象已经存在*/
String& String::operator =(const char*s){
    if(str) delete str;  
        str = new char[strlen(s) + 1];
    strcpy(str,s);
    return *this;
}

/* 重载 =  */
String& String::operator = (const String &s){
    if(this!=&s){
        if(str) delete str;  
        str = new char[strlen(s.str) + 1];
        strcpy(str,s.str);
    }
    return *this;
}

/* 友元函数重载 << */
std::ostream& operator <<(std::ostream& o, const String &s) {    
    o << s.str << std::endl;
    return o;
}

int main() 
{
    
    return 0;
}
View Code

  2、JudgePaper类

  1)答案字符串空间等长,非防御性编程

#include <iostream>
#include <string.h>
using namespace std;

class JudgePaper{
    char **paperAnswer; //试卷答案
    int count;//答题数
    int len;  //答案最大长度
public:
    JudgePaper(int count, int len):count(count),len(len){
        paperAnswer = new char*[count]; 
        for(int i=0; i<count; ++i )
            paperAnswer[i] = new char[len];
    }
    ~JudgePaper(){
        for(int i=0; i<count; ++i )
            delete [] paperAnswer[i];
        delete [] paperAnswer;
    }
    bool judgeAnswer(const char* str, int index){
        return 0 == strcmp(paperAnswer[index-1],str);
    }
    void setAnswer(const char* str, int index){
        strcpy(paperAnswer[index-1],str);
    }
};
int main()
{
    cout << "请输入试题数及最长答案长度:\n";
    int count, len;
    cin >> count >> len;    //设置试题数及最长答案长度
    JudgePaper  jp(count,len);  
    
    char answer[256];
    int index;
    
    cout << "请录入试题答案及题号:\n";
    for(int i=0; i<count; ++i){    
        cin >> answer >> index;  //设置答案及题号
        jp.setAnswer(answer,index);
    }        
    
    cout << "请输入试题答案及题号:\n";
    for(int j=0; j<count; ++j){
        cin >> answer >> index;//输入学生答案及题号
        if(jp.judgeAnswer(answer,index)) //判断
            cout << "Right!" << endl;
        else
            cout << "Wrong!" << endl;
    }        
    return 0;
}
View Code

  2)异常处理,答案字符串不等长,字符串空间动态生成

#include <iostream>
#include <exception>
#include <string.h>
using namespace std;

class JudgePaper{
    char **paperAnswer; //试卷答案
    int count;//答题数
public:
    JudgePaper(int count):count(count){
        if(!count) throw "count error!"; 
        paperAnswer = new char*[count]; 
        for(int i=0; i<count; ++i ){
            paperAnswer[i] = new char[1]; //析构            
        }           
    }
    ~JudgePaper(){
        for(int i=0; i<count; ++i )
            delete [] paperAnswer[i];
        delete [] paperAnswer;
    }
    bool judgeAnswer(const char* str, int index){
        if(index-1<0 || index>count) throw "index error!";
        return 0 == strcmp(paperAnswer[index-1],str);
    }
    void setAnswer(const char* str, int index){
        if(index-1<0 || index>count) throw "index error!";
        delete []paperAnswer[index-1];
        paperAnswer[index-1] = new char[strlen(str)+1];
        strcpy(paperAnswer[index-1],str);         
    }
};
int main()
{
    cout << "请输入试题数:\n";
    int count;
    cin >> count;   //设置试题数
    JudgePaper  jp(count);  
    
    char answer[256];
    int index;
    
    try{
        cout << "请录入试题答案及题号:\n";
        for(int i=0; i<count; ++i){    
            cin >> answer >> index;  //设置答案及题号
            jp.setAnswer(answer,index);
        }          
    }catch(const char* e){
        cout << e << endl;
    }
    
    try{
        cout << "请输入试题答案及题号:\n";
        for(int j=0; j<count; ++j){
            cin >> answer >> index;//输入学生答案及题号
            if(jp.judgeAnswer(answer,index)) //判断
                cout << "Right!" << endl;
            else
                cout << "Wrong!" << endl;
        }     
    }catch(const char* e){
        cout << e << endl;
    }    
    return 0;
}
View Code

  3)设定试卷类,答题类,判题类(或函数)

#include <iostream>
#include <exception>
#include <string.h>
using namespace std;
class Paper{
protected:
    char **paperAnswer; //试卷答案
    int count;//答题数
public:
    Paper(int count):count(count){
        if(count<=0) throw "count error!"; 
        paperAnswer = new char*[count]; 
        for(int i=0; i<count; ++i ){
            paperAnswer[i] = new char[1]; //析构            
        }           
    }
    ~Paper(){
        for(int i=0; i<count; ++i )
            delete [] paperAnswer[i];
        delete [] paperAnswer;
    }
    void setAnswer(const char* str, int index){
        if(index-1<0 || index>count) throw "index error!";
        delete []paperAnswer[index-1];
        paperAnswer[index-1] = new char[strlen(str)+1];
        strcpy(paperAnswer[index-1],str);         
    }
};

class AnswerPaper:public Paper{
public:
    AnswerPaper(int count):Paper(count) { }
    void startAnswer(){
        cout << "请输入试题答案及题号:\n";
        char answer[256];
        int index;
        for(int j=0; j<count; ++j){
            std::cin >> answer >> index;
            setAnswer(answer,index);
        }    
    }
    char* getAnswer(int index){
        return paperAnswer[index-1];
    }
    int getCount(){
        return count;
    }
};

class JudgeAnswer{ //也可以用一个函数
public:
    void judgeAnswer(AnswerPaper &teacher, AnswerPaper &student){    
        int count = student.getCount();    
        cout << "判题结果如下:\n";
        for(int i=1; i<=count; ++i){  /* 从第一题开始判断 */
            if(0 == strcmp(teacher.getAnswer(i),student.getAnswer(i)))
                cout << i << ":" << "Right!\n";
            else
                cout << i << ":" << "Wrong!\n"; 
        }      
    }
};

int main()
{
    int count;
    cout << "请输入试题数:\n";
    cin >> count;   //设置试题数
    
    try{
        AnswerPaper teacher(count); //老师答题
        teacher.startAnswer();
        AnswerPaper student(count); //学生答题 
        student.startAnswer();
        JudgeAnswer ja;
        ja.judgeAnswer(teacher,student);//判题
    }catch(const char* e){
        cout << e << endl;
    }
    return 0;
}
View Code

  4)设定试卷类,答题类,判题类(封装老师标准答案并判题),试卷类专注于试卷的构造析构,答题类专注于试卷的答题(封装)、查询答案及答题数,答题类主要对试卷类的数据成员进行操作,应是继承关系,判题类对教师答题对象进行了封装,可以设定标准答案并判题

#include <iostream>
#include <exception>
#include <string.h>
using namespace std;
class Paper{
public:
    Paper(int count):count(count){
        if(count<=0) throw "count error!"; 
        paperAnswer = new char*[count]; 
        for(int i=0; i<count; ++i ){
            paperAnswer[i] = new char[1]; //析构 
            paperAnswer[i][0] = '\0';
        }           
    }
    ~Paper(){
        for(int i=0; i<count; ++i )
            delete [] paperAnswer[i];
        delete [] paperAnswer;
    }
protected:
    char **paperAnswer; //试卷答案
    int count;//答题数
};

class AnswerPaper:public Paper{
public:
    AnswerPaper(int count):Paper(count) { startAnswer(); }
    char* getAnswer(int index){
        return paperAnswer[index-1];
    }
    int getCount(){
        return count;
    }
private:
    void startAnswer(){
        cout << "请输入试题答案及题号:\n";
        char answer[256];
        int index;
        for(int j=0; j<count; ++j){
            std::cin >> answer >> index;        
            setAnswer(answer,index);
        }    
    }
    void setAnswer(const char* str, int index){
        if(index-1<0 || index>count || paperAnswer[index-1][0]) throw "index error!";
        delete []paperAnswer[index-1];
        paperAnswer[index-1] = new char[strlen(str)+1];
        strcpy(paperAnswer[index-1],str);         
    }
};

class JudgeAnswer{ //老师判题
private:
    AnswerPaper *teacher;
public:
    JudgeAnswer(int count): teacher(new AnswerPaper(count)) { }
    void judgeAnswer(AnswerPaper &student){    
        int count = student.getCount();    
        cout << "判题结果如下:\n";
        for(int i=1; i<=count; ++i){  /* 从第一题开始判断 */
            if(0 == strcmp(teacher->getAnswer(i),student.getAnswer(i)))
                cout << i << ":" << "Right!\n";
            else
                cout << i << ":" << "Wrong!\n"; 
        }      
    }
    ~JudgeAnswer(){
        delete teacher;
    } 
};

int main()
{
    int count;
    cout << "请输入试题数:\n";
    cin >> count;   //设置试题数
    
    try{
        cout << "老师设置标准答案:\n";
        JudgeAnswer teacher(count);  //教师设置标准答案
        cout << "学生答题:\n";
        AnswerPaper student(count);  //学生答题 
        teacher.judgeAnswer(student);//教师判题
    }catch(const char* e){
        cout << e << endl;
    }
    return 0;
}
View Code

  异常处理,循环测试主函数

//异常处理, 循环输入
int main()
{   
    int flag = 0;
    while(!flag)
    {        
        flag = 1;    
        int count;
        cout << "请输入试题数:\n";
        cin >> count;   //设置试题数
        try{
            cout << "老师设置标准答案:\n";
            JudgeAnswer teacher(count);  //教师设置标准答案
            cout << "学生答题:\n";
            AnswerPaper student(count);  //学生答题 
            teacher.judgeAnswer(student);//教师判题
        }catch(const char* e){
            cout << e << endl;
            flag = 0;
        }
    }
    return 0;
}
View Code

  5)试卷类,答题类从逻辑上看,不应当是继承关系,若答题类set试卷类数据成员(即答题行为),应调用试卷类的成员函数,set又不应该是试卷类的行为,从包含关系上看(使用关系),如何实现不添加试卷类成员函数或改变访问控制,又可以访问试卷类的数据成员?把答题类设置为试卷类的友元类,或试卷类设为答题类的内部类都可以解决这个问题,同时可以完全封装试卷类,然后答题类数据成员,添加一个试卷类指针即可

#include <iostream>
#include <exception>
#include <string.h>
using namespace std;
class AnswerPaper; //类声明
class Paper{
private:
    friend AnswerPaper; //友元类
    char **paperAnswer; //试卷答案
    int count;//答题数
    Paper(int count):count(count){
        if(count<=0) throw "count error!"; 
        paperAnswer = new char*[count]; 
        for(int i=0; i<count; ++i ){
            paperAnswer[i] = new char[1]; //析构 
            paperAnswer[i][0] = '\0';
        }           
    }
    ~Paper(){
        for(int i=0; i<count; ++i )
            delete [] paperAnswer[i];
        delete [] paperAnswer;
    }   
};

class AnswerPaper{
public:
    AnswerPaper(int count):p(new Paper(count)) { startAnswer(); }
    ~AnswerPaper(){ delete p; }
    char* getAnswer(int index){
        return p->paperAnswer[index-1];
    }
    int getCount(){
        return p->count;
    }
private:
    Paper *p; //试卷指针
    void startAnswer(){
        cout << "请输入试题答案及题号:\n";
        char answer[256];
        int index;
        for(int j=0; j<p->count; ++j){
            std::cin >> answer >> index;        
            setAnswer(answer,index);
        }    
    }
    void setAnswer(const char* str, int index){
        if(index-1<0 || index>p->count || p->paperAnswer[index-1][0]) 
            throw "index error!";
        delete [] p->paperAnswer[index-1];
        p->paperAnswer[index-1] = new char[strlen(str)+1];
        strcpy(p->paperAnswer[index-1],str);         
    }
};

class JudgeAnswer{ //老师判题
private:
    AnswerPaper *teacher;
public:
    JudgeAnswer(int count): teacher(new AnswerPaper(count)) { }
    void judgeAnswer(AnswerPaper &student){    
        int count = student.getCount();    
        cout << "判题结果如下:\n";
        for(int i=1; i<=count; ++i){  /* 从第一题开始判断 */
            if(0 == strcmp(teacher->getAnswer(i),student.getAnswer(i)))
                cout << i << ":" << "Right!\n";
            else
                cout << i << ":" << "Wrong!\n"; 
        }      
    }
    ~JudgeAnswer(){
        delete teacher;
    } 
};

int main()
{
    int count;
    cout << "请输入试题数:\n";
    cin >> count;   //设置试题数
    
    try{
        cout << "老师设置标准答案:\n";
        JudgeAnswer teacher(count);  //教师设置标准答案
        cout << "学生答题:\n";
        AnswerPaper student(count);  //学生答题 
        teacher.judgeAnswer(student);//教师判题
    }catch(const char* e){
        cout << e << endl;
    }
    return 0;
}
View Code