从文件填充对象矢量

时间:2015-03-13 07:38:36

标签: c++

我正在尝试编写一个函数,它填充文件中的对象向量,但我的程序在启动时会立即崩溃。这是对程序应该做什么的简要说明。 该计划本身基于具有多个专业,课程(当前的学习年度)和团体。组对象还有一个向量,由组中的学生组成。他们的成员变量是姓名,社会安全号码(EGN),教师编号(FN)和地图,其中包含学生所做的各种测试。地图对是测试代码和获得的分数 - 学生在地图中不能多次使用相同的测试代码。程序中还有其他功能,但它们工作得很好,除了那些还没有机身的功能。 根据他们的小组,我从文件中提取学生的想法是提交两个参数,当我调用函数时 - 一个找到具有正确组的行,另一个用作分隔符,以便停止阅读。该文件具有这种结构:

KST11
Ivan 9402184050 61360133 1 55 2 90 3 78
Kaloqn 9407132530 61360148 1 25 2 80 3 87
KST12
Anton 9402195020 61360138 1 20 2 80 3 92
KST21
KST22
SIT11
SIT12
SIT21
SIT22

ReadFile()函数正确打开文件,但是当程序尝试读取时会导致程序崩溃。

#include <iostream>
#include <fstream>
#include <map>
#include <ctime>
#include <string>
#include <stdlib.h>
#include <vector>
#include <list>
#include <iterator>
#include <algorithm>
#include <utility>
using namespace std;

class CPerson
{
private:
string name;
string EGN;

public:
CPerson()
{
    name=" ";
    EGN=" ";
}

CPerson(const string n, const string e)
{
    name=n;
    EGN=e;
}

string getname()const
{
    return name;
}

string getEGN()const
{
    return EGN;
}

void setname(const string n)
{
    name=n;
}

void setEGN(const string e)
{
    EGN=e;
}

virtual void print() = 0; //1.1

int getAge() const //1.2
{
    int age;
    time_t now = time(0);
    tm *ltm = localtime(&now);
    int year = atoi(getEGN().substr(0, 2).c_str());
    int month = atoi(getEGN().substr(2, 2).c_str());
    int day = atoi(getEGN().substr(4, 2).c_str());
    int cyear = 1900 + ltm->tm_year;
    int cmonth = 1 + ltm->tm_mon;
    int cday = 1 + ltm->tm_mday;

    age = cyear - (year + 1900);
    if (cmonth < month)
        age--;
    if (cmonth == month && cday < day)
        age--;
    return age;
}
};

class CStudent: public CPerson
{
private:
string FN;
map<int, int> st_tests;

public:
CStudent()
{
    FN=" ";
}

CStudent(const string n)
{
    FN=n;
}

CStudent(const string o, const string p, const string n):CPerson(o,p)
{
     FN=n;
}

void setFN(const string n)
{
    FN=n;
}

void setst_tests(map<int, int> m)
{
    st_tests=m;
}

string getFN() const
{
    return FN;
}

map<int, int> getst_tests()
{
    return st_tests;
}

void print()
{
    cout<<"Ime: "<<getname()<<endl;
    cout<<"EGN: "<<getEGN()<<endl;
    cout<<"FN: "<<getFN()<<endl;
    map<int, int>::iterator it=st_tests.begin();
    while(it!=st_tests.end())
    {
        cout<<it->first<<" "<<it->second<<endl;
        it++;
    }
}

void add_st_tests(int a, int b)
{
     st_tests.insert(pair<int,int>(a,b));
}

double average() //2.1
{
    double sum=0;
    map<int, int>::iterator it=st_tests.begin();
    for (it=st_tests.begin();it!=st_tests.end();it++)
        sum+=it->second;
    if(st_tests.size()!=0)
        return sum/st_tests.size();
    return -1;
}

int search(const int a) //2.2
{
    map<int, int>::iterator it=st_tests.find(a);
    return it->second;
}

bool operator () (CStudent a, CStudent b) const
{
        return a.average() > b.average();
}
};

class CGroup
{
private:
string spec;
int kurs;
int grupa;
vector<CStudent> students;

public:
string getspec() const
{
    return spec;
}

int getkurs() const
{
    return kurs;
}

int getgrupa() const
{
    return grupa;
}

vector<CStudent> getstudents()
{
    return students;
}

void setstudents(vector<CStudent> a)
{
    students=a;
}

void setspec(const string n)
{
    spec=n;
}

void setkurs(const int n)
{
    kurs=n;
}

void setgrupa(const int n)
{
    grupa=n;
}

CGroup(const string a, const int b, const int c)
{
    spec=a;
    kurs=b;
    grupa=c;

}

void addstudent(CStudent &a)
{
     students.push_back(a);
}

int ReadFile(const string gr, const string stop) //3.1
{
    ifstream st;
    st.open("students.txt",ios::in);
    if(!st)
    {
        cout<<"Cannot open students.txt or file does not exist."<<endl;
        return 0;
    }
    string a, b, c, mov;
    int d, e, i=0;
    do
    {
        getline(st,mov);
    }while(mov != gr);
    do
    {
        st >> a >> b >> c;
        students[i].setname(a);
        students[i].setEGN(b);
        students[i].setFN(c);
        do
        {
            st >> d >> e;
            students[i].add_st_tests(d,e);
        }while(st.peek() != '\n' || st.peek() != '\r');
        i++;
        getline(st,mov);
    }while(mov != stop || !st.eof());
    st.close();
}

double averagetest(int a)  //3.2
{
    double sum=0;
    int br=0;
    vector<CStudent>::iterator itt;
    for (itt=students.begin();itt!=students.end();itt++)
    {
        map<int, int>::iterator it=(*itt).getst_tests().find(a);
        sum+=it->second;
        br++;
    }
    cout<<sum/br;
    return sum/br;
}

list<CStudent> averageparam(const int a, const int b) //3.3
{
    list<CStudent> l;
    int i=0;
    vector<CStudent>::iterator itt=students.begin();
    for (itt=students.begin();itt!=students.end();itt++)
    {
        if((*itt).average() >= a && (*itt).average() <= b)
            l.push_back(*itt);
        i++;
    }
    cout<<"List ot studenti sus sreden broi tochki mejdu "<<a<<" - "<<b<<endl;
    list<CStudent>::iterator it=l.begin();
    for (it=l.begin();it!=l.end();it++)
        (*it).print();
    return l;
}

int averageabove(const int a) //3.4
{
    int br=0;
    vector<CStudent>::iterator itt=students.begin();
    for (itt=students.begin();itt!=students.end();itt++)
        if((*itt).average() > a)
            br++;
    cout<<"Broi studenti sus sreden broi tochki nad "<<a<<": "<<br<<endl;
    return br;
}

void averageage(const int a) //3.5
{
    cout<<"Sreden uspeh na "<<a<<" godishni studenti."<<endl;
    vector<CStudent>::iterator itt=students.begin();
    for (itt=students.begin();itt!=students.end();itt++)
    {
        int b=(*itt).getAge();
        if(a == b)
            cout<<(*itt).getname()<<" "<<(*itt).average()<<endl;
    }
}

void beststudent() //3.6
{
    cout<<"Student s nai-visoka uspevaemost."<<endl;
    CStudent temp;
    vector<CStudent>::iterator itt=students.begin();
    for (itt=students.begin();itt!=students.end();itt++)
        if ((*itt).average() > temp.average())
        temp = (*itt);
    temp.print();
}

void sortaverage() //3.7
{
    sort(students.begin(),students.end(),CStudent());
    cout<<"Sortini studenti po sreden broi tochki."<<endl;
    vector<CStudent>::iterator itt=students.begin();
    for (itt=students.begin();itt!=students.end();itt++)
        (*itt).print();
}

void sortasc() //3.8
{

}

void averageage() //3.9
{

}
};

int main()
{
CGroup KST11 ("KST",1,1); KST11.ReadFile("KST11","KST12");
CGroup KST12 ("KST",1,2);
CGroup KST13 ("KST",1,3);
CGroup KST21 ("KST",2,1);
CGroup KST22 ("KST",2,2);
CGroup KST23 ("KST",2,3);
CGroup SIT11 ("SIT",1,1);
CGroup SIT12 ("SIT",1,2);
CGroup SIT13 ("SIT",1,3);
CGroup SIT21 ("SIT",2,1);
CGroup SIT22 ("SIT",2,2);
CGroup SIT23 ("SIT",2,3);
}

在这一行“KST11.ReadFile(”KST11“,”KST12“);”,我通过提交学生的起点和终点来调用KST11组的函数ReadFile()被阅读。我不完全确定这是否是正确的做法。

调试结果:

Building to ensure sources are up-to-date
Selecting target: 
Debug
Adding source dir: C:\Users\IvailoCOMP\Desktop\Kursov Proekt N.9\
Adding source dir: C:\Users\IvailoCOMP\Desktop\Kursov Proekt N.9\
Adding file: C:\Users\IvailoCOMP\Desktop\Kursov Proekt N.9\bin\Debug\Kursov Proekt N.exe
Changing directory to: C:/Users/IVAILO~1/Desktop/KURSOV~1.9/.
Set variable: PATH=.;C:\Program Files\CodeBlocks\MinGW\bin;C:\Program Files\CodeBlocks\MinGW;C:\ProgramData\Oracle\Java\javapath;C:\watcom-1.3\binnt;C:\watcom-1.3\binw;C:\Program Files\NVIDIA Corporation\PhysX\Common;C:\Windows\System32;C:\Windows;C:\Windows\System32\wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Program Files\Microsoft\Web Platform Installer;C:\Program Files\Microsoft ASP.NET\ASP.NET Web Pages\v1.0;C:\Program Files\Windows Kits\8.0\Windows Performance Toolkit;C:\Program Files\Microsoft SQL Server\110\Tools\Binn
Starting debugger: C:\Program Files\CodeBlocks\MINGW\bin\gdb.exe -nx -fullname  -quiet  -args C:/Users/IVAILO~1/Desktop/KURSOV~1.9/bin/Debug/KURSOV~1.EXE
done
Registered new type: wxString
Registered new type: STL String
Registered new type: STL Vector
Setting breakpoints
Debugger name and version: GNU gdb (GDB) 7.5
Child process PID: 2748
Program received signal SIGSEGV, Segmentation fault.
In std::string::assign(std::string const&) () ()

Call Stack
#0 0044C9F8 std::string::assign(std::string const&) ()
#1 DFDEDDDC ?? ()
#2 E3E2E1E0 ?? () (??:??)
#3 00402758 check_exception_spec(lsda_header_info*, std::type_info const*, void*, long) ()
#4 ??   ?? ()

1 个答案:

答案 0 :(得分:1)

您应该在想要对其进行操作之前将项目添加到矢量

    students[i].setname(a);
    students[i].setEGN(b);
    students[i].setFN(c);

还有另一个问题是偷看&#39;用于查找一行的结尾。 ReadFile的以下实现应解决问题。

CStudent readStudent(const std::string& line)
{
   string a, b, c;
   int d, e;
   std::istringstream linestream(line);
   linestream >> a >> b >> c;
   CStudent student;
   student.setname(a);
   student.setEGN(b);
   student.setFN(c);
   while(true)
   {
        linestream >> d >> e;
        if(!linestream.good())
        {
            break;
        }
        student.add_st_tests(d,e);
   }
   return student;
}

void ReadFile(const string gr, const string stop) //3.1
   {
   ifstream st;
   st.open("students.txt",ios::in);
   if(!st)
   {
        cout<<"Cannot open students.txt or file does not exist."<<endl;
        return;
    }
    string mov;
    do
    {
        getline(st,mov);
    } while(mov != gr);
    while(true)
    {
        getline(st,mov);
        if(mov == stop || !st.eof())
        {
            break;
        }
        CStudent student = readStudent(mov);

        students.push_back(student);
    }
    st.close();
}