C++ 如何在读取文件后构建不同对象的向量

C++ 如何在读取文件后构建不同对象的向量,c++,C++,各位!!我是C++的新手,现在正在做C++项目。整个结构已经完成,但是我一直在想< /P> 如何构建不同对象的向量以及如何从一开始就读取文件 在我的问题中,首先我必须读取一个具有以下格式的readReshibles(std::istream&fs)的txt文件: 矩形12.5 2 0.2 圈1 2.5 1.2 矩形4 2 0.3 (每个障碍物开始一条新线) 我需要读取不同障碍物的数据信息,并将这些障碍物存储在向量中。 类障碍是具有两个子类圆形和矩形的基类。 我尝试将这些不同的障碍(我认为应该有它

各位!!我是C++的新手,现在正在做C++项目。整个结构已经完成,但是我一直在想< /P> 如何构建不同对象的向量以及如何从一开始就读取文件

在我的问题中,首先我必须读取一个具有以下格式的readReshibles(std::istream&fs)的txt文件:

矩形12.5 2 0.2
圈1 2.5 1.2
矩形4 2 0.3

(每个障碍物开始一条新线)

我需要读取不同障碍物的数据信息,并将这些障碍物存储在向量中。
类障碍是具有两个子类圆形和矩形的基类。
我尝试将这些不同的障碍(我认为应该有它们的数据信息)放在障碍向量中,然后调用它们都有的虚拟函数

下面是我尝试使用的代码:

vector<Obstacle> obsdata; 

Myworld::readObstacles(std::istream &fs)
{
    std::string shape;
    double num1,num2,num3,num4,num5;
    while(fs>>shape>>num1>>num2>>num3>>num4>>num5)
    {
        if(shape=="CIRCLE") {
            CIRCLE c;
            c.m_Xc=num1;
            c.m_Yc=num2;
            c.m_Radius=num3;       
            obsdata.push_back(c);
        }

        if(shape=="RECTANGLE") {
            RECTANGLE r;
            r.center_x=num1;
            r.center_y=num2;    
            r.width=num3;
            r.height=num4;
            r.angle=num5;
            obsdata.push_back(r);
        }
    }
}

MyWorld::writeMatlabDisplayCode(std::ostream &fs)
{
    for( i = 0; i < obsdata.size(); i++ )
        obsdata[i].writeMatlabDisplayCode(fs);
}
矢量数据;
Myworld::ReadRestribles(标准::istream&fs)
{
字符串形状;
双num1、num2、num3、num4、num5;
而(fs>>形状>>num1>>num2>>num3>>num4>>num5)
{
如果(形状=“圆”){
圈c;
c、 m_Xc=num1;
c、 m_Yc=num2;
c、 m_半径=num3;
obsdata.push_back(c);
}
如果(形状=“矩形”){
矩形r;
r、 中心x=num1;
r、 中心y=num2;
r、 宽度=num3;
r、 高度=num4;
r、 角度=num5;
obsdata.push_back(r);
}
}
}
MyWorld::writeMatlabDisplayCode(std::ostream&fs)
{
对于(i=0;i
我知道这不管用,但我不知道该怎么办


任何话都会有帮助。谢谢

存在一个称为切片的问题:如果复制到包含基类实例的向量,则会丢失派生类中的数据

不过,您可以使用指向基的指针向量:

std::vector<Obstacle*> obsdata;
RECTANGLE r = new RECTANGLE;
// set properties
obsdata.push_back(r);
// use it later, e.g.:
obsdata[0]->writeMatlabDisplayCode(fs);
// clean up when you don't need obstacles anymore:
for(std::vector<Obstacle*>::iterator it = obsdata.begin(); it != obsdata.end(); ++it)
    delete *it;
std::向量obsdata;
矩形r=新矩形;
//设置属性
obsdata.push_back(r);
//以后再使用,例如:
obsdata[0]->writeMatlabDisplayCode(fs);
//当你不再需要障碍物时进行清理:
对于(std::vector::iterator it=obsdata.begin();it!=obsdata.end();++it)
删除*它;

你也应该避免每次读5个数字。相反,您可以读取障碍描述,然后根据具体障碍需要读取尽可能多的数字。

您遇到了一个称为切片的问题:如果复制到包含基类实例的向量,则会丢失派生类中的数据

不过,您可以使用指向基的指针向量:

std::vector<Obstacle*> obsdata;
RECTANGLE r = new RECTANGLE;
// set properties
obsdata.push_back(r);
// use it later, e.g.:
obsdata[0]->writeMatlabDisplayCode(fs);
// clean up when you don't need obstacles anymore:
for(std::vector<Obstacle*>::iterator it = obsdata.begin(); it != obsdata.end(); ++it)
    delete *it;
std::向量obsdata;
矩形r=新矩形;
//设置属性
obsdata.push_back(r);
//以后再使用,例如:
obsdata[0]->writeMatlabDisplayCode(fs);
//当你不再需要障碍物时进行清理:
对于(std::vector::iterator it=obsdata.begin();it!=obsdata.end();++it)
删除*它;

你也应该避免每次读5个数字。相反,您可以阅读障碍物描述,然后根据具体障碍物的需要读取尽可能多的数字。

如果您有一个指针向量,您可以这样做:

vector<Obstacle *> obsdata;

等等

如果你有一个指针向量,你可以这样做:

vector<Obstacle *> obsdata;

等等。

while循环的条件是一个问题。圆形比矩形少2个条目。我建议您先阅读形状,然后根据类型读取其余数据。您知道可以读取3个圆数据点和5个矩形数据点

一些伪代码

while( fs >> shape )
{
  if( shape == "CIRCLE" )
  { 
        CIRCLE c;
        fs >> c.m_Xc;
        fs >> c.m_Yc;
        fs >> c.m_Radius;       
        obsdata.push_back(c);
   }

  if( shape == "RECTANGLE" )
  {
      RECTANGLE r;
      fs >> r.center_x;
      fs >> r.center_y;    
      fs >> r.width;
      fs >> r.height;
      fs >> r.angle;
      obsdata.push_back(r);
  }
}

如GF在注释中建议的,标准库上的一本好的C++书籍或教程会有帮助。

你的while循环的条件是个问题。圆形比矩形少2个条目。我建议您先阅读形状,然后根据类型读取其余数据。您知道可以读取3个圆数据点和5个矩形数据点

一些伪代码

while( fs >> shape )
{
  if( shape == "CIRCLE" )
  { 
        CIRCLE c;
        fs >> c.m_Xc;
        fs >> c.m_Yc;
        fs >> c.m_Radius;       
        obsdata.push_back(c);
   }

  if( shape == "RECTANGLE" )
  {
      RECTANGLE r;
      fs >> r.center_x;
      fs >> r.center_y;    
      fs >> r.width;
      fs >> r.height;
      fs >> r.angle;
      obsdata.push_back(r);
  }
}

正如GF在评论中建议的,标准库上的一本好的C++书籍或教程会有帮助。

你可以一次只读取整行,然后标记值……/p>
vector<Obstacle*> obsdata;

string line;
while(getline(fs, line)) {
    char *token = strtok(line.c_str(), " ");
    string shape(token);

    vector<double> numbers;
    stringstream ss;
    while(token = strtok(NULL, " ")) {
        double d;
        ss << token;
        ss >> d;

        numbers.push_back(d);
    }

    if(shape == "CIRCLE") {
        CIRCLE *c = new CIRCLE();
        c->m_Xc=numbers[0];
        c->m_Yc=numbers[1];
        c->m_Radius=numbers[2];       
        obsdata.push_back(c);
    } else if(shape == "RECTANGLE") {
        RECTANGLE *r = new RECTANGLE();
        r->center_x=numbers[0];
        r->center_y=numbers[1];    
        r->width=numbers[2];
        r->height=numbers[3];
        r->angle=numbers[4];
        obsdata.push_back(r);
    }
}
矢量数据;
弦线;
while(getline(fs,line)){
char*token=strtok(line.c_str(),“”);
字符串形状(标记);
向量数;
细流ss;
while(token=strtok(NULL,“”){
双d;
ss>d;
数字。推回(d);
}
如果(形状=“圆”){
圆*c=新圆();
c->m_Xc=数字[0];
c->m_Yc=数字[1];
c->m_半径=数字[2];
obsdata.push_back(c);
}else if(形状=“矩形”){
矩形*r=新矩形();
r->center_x=数字[0];
r->center_y=数字[1];
r->宽度=数字[2];
r->高度=数字[3];
r->角度=数字[4];
obsdata.push_back(r);
}
}
我会删除MyWorld析构函数中的指针向量:

~MyWorld() {
    // loop thanks to gf
    for(std::vector<Obstacle*>::iterator it = obsdata.begin(); it != obsdata.end(); ++it)
        delete *it;  
}
~MyWorld(){
//感谢gf
对于(std::vector::iterator it=obsdata.begin();it!=obsdata.end();++it)
删除*它;
}

您可以尝试一次读取整行,然后标记值

vector<Obstacle*> obsdata;

string line;
while(getline(fs, line)) {
    char *token = strtok(line.c_str(), " ");
    string shape(token);

    vector<double> numbers;
    stringstream ss;
    while(token = strtok(NULL, " ")) {
        double d;
        ss << token;
        ss >> d;

        numbers.push_back(d);
    }

    if(shape == "CIRCLE") {
        CIRCLE *c = new CIRCLE();
        c->m_Xc=numbers[0];
        c->m_Yc=numbers[1];
        c->m_Radius=numbers[2];       
        obsdata.push_back(c);
    } else if(shape == "RECTANGLE") {
        RECTANGLE *r = new RECTANGLE();
        r->center_x=numbers[0];
        r->center_y=numbers[1];    
        r->width=numbers[2];
        r->height=numbers[3];
        r->angle=numbers[4];
        obsdata.push_back(r);
    }
}
矢量数据;
弦线;
while(getline(fs,line)){
char*token=strtok(line.c_str(),“”);
字符串形状(标记);
向量数;
细流ss;
while(token=strtok(NULL,“”){
双d;
ss>d;
数字。推回(d);
}
如果(形状=“圆”){
圆*c=新圆();
c->m_Xc=数字[0];
c->m_Yc=数字[1];
c->m_半径=数字[2];
obsdata.push_back(c);
}else if(形状=“矩形”){
矩形*r=新矩形();
r->center_x=数字[0];
r->center_y=数字[1];
r->宽度=数字[2];
r->高度=数字[3];
r->角度=数字[4];
obsdata.push_back(r);
}
}