我正在尝试编写一个函数,它填充文件中的对象向量,但我的程序在启动时会立即崩溃。这是对程序应该做什么的简要说明。 该计划本身基于具有多个专业,课程(当前的学习年度)和团体。组对象还有一个向量,由组中的学生组成。他们的成员变量是姓名,社会安全号码(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 ?? ?? ()
答案 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();
}