2015-03-13 126 views
0

我正在尝试编写一个函数,它从文件中填充对象的矢量,但是我的程序在启动时会立即崩溃。以下是该程序应该做什么的简要说明。 该计划本身是基于多个专业,课程(当前的学习年)和团体。该组对象也有一个矢量,由该组的学生组成。他们的成员变量是姓名,社会安全号码(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’);”,我调用函数ReadFile的()为集团KST11提交学生的起点和终点,这些将被读取。我不完全确定这是否是正确的做法。

调试结果:

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

TL; DR!请使用调试器来定位发生崩溃的位置,然后编辑您的问题以仅包含相关代码。 – 2015-03-13 07:41:00

+0

然而,一个好主意可能是看看你是否打电话给在调用'ReadFile'之前,'addstudent'足够多次。 – 2015-03-13 07:43:21

+0

不幸的是,我不熟悉如何使用调试工具,所以我只是发布它创建的消息。 – Arirang 2015-03-13 08:18:01

回答

1

您应该添加项目到矢量你想运行它

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

也有与“偷看”使用情况,以找到结束另一个问题之前,一条线。以下实施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(); 
} 
+0

应该删除行if(mov == stop ||!st.eof())中的感叹号,但它并不是什么大事。非常感谢您解决有问题的功能。 – Arirang 2015-03-13 15:17:01