多次从ifstream读取

Reading from ifstream multiple times

本文关键字:读取 ifstream      更新时间:2023-10-16

如果这是一个非常简单的问题,我很抱歉,但我对C++还很陌生,而且我正在进行的项目遇到了麻烦。

该项目的一部分涉及将对象的信息写入.txt文件,并能够读取该.txt文件以加载到对象中。(在这种情况下,信息是写的,而不是对象本身,这样人们就可以很容易地编辑.txt来更改对象)。

我调用的从.txt文件中读取的函数如下:

void Room::load(ifstream& inFile)
{
string garbage;
string str;
inFile >> garbage >> garbage >> mId;
inFile >> garbage; getline(inFile, mName);
inFile >> garbage; getline(inFile, mDesc);
loadVec(garbage, inFile, mExits);
}

"垃圾"被用来清除.txt中的描述符,以帮助用户。

一个典型的房间对象应该如下所示:

Room ID: 2
Name: Foyer
Description: The player can enter here from the kitchen.
Exits: 3 4 

当我尝试加载多个文件室时,会出现问题。第一个房间将完全加载,但任何后续房间都将无法正确加载。

我至少预计它会失败,因为.txt文件中的第一个文件室会被重复加载,但事实并非如此。

我将非常感谢任何人能提供的帮助,提前表示感谢。

编辑:目前,我正在使用以下代码加载房间:

if (inFile)
    {
    //Assign data to objects
    room0.load(inFile);
    room1.load(inFile);
    }

在这种情况下,room0最终将第一个房间的数据保存在.txt文件中,但room1保持不变,只是出于某种原因清除了其出口。

目前测试程序给出以下结果:

BEFORE LOAD
ID= -1
NAME= Nowhere
DESC= There's nothing here.
Exits= -1
ID= -1
NAME= Nowhere
DESC= There's nothing here.
Exits= -1
AFTER LOAD
ID= 1
NAME=  Kitchen
DESC=  This is the first room the player will see.
Exits= 2 3 5 6
ID= -1
NAME= Nowhere
DESC= There's nothing here.
Exits=
Press any key to continue . . .

这些房间在加载之前和加载之后分别是房间0和房间1。

loadVec函数如下所示:

//Loads consecutive integers from inFile, saving them to vec
void loadVec(string& garbage, ifstream& inFile, vector<int>& vec)
{
int num;
vec.clear();
inFile >> garbage >> num;
vec.push_back(num);
while (inFile)
{
    inFile >> num;
    vec.push_back(num);
}
vec.erase(vec.begin() + vec.size() - 1);
}

以及程序应该从中加载的未编辑的.txt文件:

Room ID: 1
Name: Kitchen
Description: This is the first room the player will see.
Exits: 2 3 5 6
Room ID: 2
Name: Foyer
Description: The player can enter here from the kitchen, they can exit to the rooms     with the IDs listed as 'Exits'.
Exits: 3 4 
Room ID: 3
Name: Bathroom
Description: This is the third room.
Exits: 4 

问题是在读取出口之后,流failbit被设置。只要设置好,它就不会读取任何内容。

您必须调用std::istream::clear来清除错误。


顺便说一下,有一种更像C++的方法可以读取向量:

std::copy(std::istream_iterator<int>(inFile),
          std::istream_iterator<int>(),
          std::back_inserter(vec));

参考文献:

  • std::copy
  • std::istream_iterator
  • std::back_inserter

当然,在执行此操作之前,您必须先阅读"标签"(garbage)。