首页 \ 问答 \ 从ifstream多次读取(Reading from ifstream multiple times)

从ifstream多次读取(Reading from ifstream multiple times)

抱歉,如果这是一个非常简单的问题,但我对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 . . .

这些房间分别在加载前后分别为room0和room1。

这是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 

Apologies if this is a really simple question but I'm fairly new to C++ and I'm having trouble with a project I'm working on.

Part of this project involves writing the information of an object to a .txt file and being able to read that .txt file to load in an object. (In this case the information is written rather than the object itself so that someone can easily edit the .txt to change an object).

The function I'm calling to read from the .txt file is as follows:

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);
}

"garbage" being used to get rid of descriptors in the .txt to help a user.

A typical room object should look something like the following:

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

My problem occurs when I try to load multiple Rooms. The first Room will load perfectly but any subsequent Room will fail to load properly.

I would have at least expected it to fail in such a way as the first room in the .txt file is loaded repeatedly but that isn't the case.

I'd be very grateful for any help anyone could offer, thanks in advance.

Edit: For now I'm loading rooms using the following code:

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

In this case, room0 winds up with the data of the first room in the .txt file but room1 remains unchanged with the exception of having its exits cleared for some reason.

Testing the program at the moment gives the following:

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 . . .

Those rooms being room0 and room1 respectively both before and after load.

Here's what the loadVec function looks like:

//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);
}

And the unedited .txt file from which the program should be loading:

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 

原文:https://stackoverflow.com/questions/20237164
更新时间:2023-02-03 22:02

最满意答案

这里的问题正如其他解释的那样,int对象是不可变的

two[0][0] = 9

不会改变旧的两个[0] [0]对象,而是会创建新对象,并使两个[0] [0]引用这个新对象(旧对象是垃圾收集,如果没有其他参考它在这种情况下有)

并且在创建两个数组之后在这种情况下更清楚我们有以下( - >表示引用)

one[0][0] --> object(1)
two[0][0] --> object(1)

然后当你出手

two[0][0] = 9

对象引用看起来像这样

one[0][0] --> object(1)
two[0][0] --> object(9)

因此,为了解决这个问题,我们需要将数组中的值更改为可变

我创建了一个非常简单的类,它保存int并使数组从中解决,这解决了你的问题

这是工作代码

class IntHolder:
    def __init__(self,int_value):
        self.intvalue = int_value
    def set_value(self,int_value):
        self.intvalue = int_value
    def __str__(self):
        return str(self.intvalue)
    def __repr__(self):
        return str(self.intvalue)
    def __str__(self):
        return str(self.intvalue)
one = [
    [IntHolder(1), IntHolder(2), IntHolder(3), IntHolder(4)],
    [IntHolder(2), IntHolder(3), IntHolder(4), IntHolder(5)],
    [IntHolder(3), IntHolder(4), IntHolder(5), IntHolder(6)],
    [IntHolder(4), IntHolder(5), IntHolder(6), IntHolder(7)]
    ]

two = [
    [one[0][0], one[0][1], one[1][0], one[1][1]],
    [one[0][2], one[0][3], one[1][2], one[1][3]],
    [one[2][0], one[2][1], one[3][0], one[3][1]],
    [one[2][2], one[2][3], one[3][2], one[3][3]]
    ]
two[0][0].set_value(9)

print one
print two

the issue here as other explained is that int objects are immutable So doing

two[0][0] = 9

wont change the old two[0][0] object instead it will create new object and make two[0][0] reference this new object (the old object is garbage collected if not other reference it in this case there is)

and to be more clear in this case after creating both arrays we have the following (--> means reference)

one[0][0] --> object(1)
two[0][0] --> object(1)

then when you excuted

two[0][0] = 9

the object reference looks like this

one[0][0] --> object(1)
two[0][0] --> object(9)

So to solve this we need to change the values that you have in the array to be mutable

I have created very simple class that hold the int and made the array out of it and that resolves your issue

here is working code

class IntHolder:
    def __init__(self,int_value):
        self.intvalue = int_value
    def set_value(self,int_value):
        self.intvalue = int_value
    def __str__(self):
        return str(self.intvalue)
    def __repr__(self):
        return str(self.intvalue)
    def __str__(self):
        return str(self.intvalue)
one = [
    [IntHolder(1), IntHolder(2), IntHolder(3), IntHolder(4)],
    [IntHolder(2), IntHolder(3), IntHolder(4), IntHolder(5)],
    [IntHolder(3), IntHolder(4), IntHolder(5), IntHolder(6)],
    [IntHolder(4), IntHolder(5), IntHolder(6), IntHolder(7)]
    ]

two = [
    [one[0][0], one[0][1], one[1][0], one[1][1]],
    [one[0][2], one[0][3], one[1][2], one[1][3]],
    [one[2][0], one[2][1], one[3][0], one[3][1]],
    [one[2][2], one[2][3], one[3][2], one[3][3]]
    ]
two[0][0].set_value(9)

print one
print two

相关问答

更多

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)