【问题标题】:The read method returns the last object twice from the fileread 方法从文件中返回最后一个对象两次
【发布时间】:2020-08-18 21:45:23
【问题描述】:

read 方法两次返回最后一个对象。我尝试在读取行之前使用tellg,似乎最后一个对象本身在文件中写入了两次。

#include<iostream>
#include<fstream>
#include<string>
using namespace std;
class Abc
{
    string uname, pword;
public:
    void getdetails()
    {
        cout << "enter a password";
        getline(cin, pword);
        cout << "enter username";
        getline(cin, uname);
    }
    void printdetails()
    {
        cout << uname << " " << pword;
    }
};
int main()
{
    fstream f;
    int i, j;
    f.open("gamma.txt", ios::out | ios::binary | ios::app);
    Abc a;
    for (i = 0; i < 2; i++)
    {
        a.getdetails();
        f.write((char*) &a, sizeof(a));
    }
    f.close();
    f.open("gamma.txt", ios::in | ios::binary);
    for (i = 0; i < 2; i++)
    {
        f.read((char*) &a, sizeof(a));
        a.printdetails();
    }
    f.close();
}

这是输出。我没有得到两个对象,而是得到第二个对象两次。

enter a password
123
enter username
ralph
enter a password
321
enter username
john
john 321john 321

【问题讨论】:

  • 您没有检查读取是否有效。所以最后一次读取失败,您只是打印a 的随机内容,这恰好是最后一次读取之前对象中的内容。要验证这一点,请在阅读之前清除内容,看看会发生什么。仅在读取成功时修复打印。
  • 附言。像这样读写字符串是有问题的(非常错误),因为对象 uname 和 pword 是具有构造函数和东西的对象。

标签: c++ file-handling


【解决方案1】:

你不能合法地 readwrite 任何你喜欢的东西。特别是,在您的情况下,不能读取或写入包含string 的结构。这样做会导致未定义的行为。

只有所谓的POD types 才能以您尝试的方式读取或写入。

【讨论】:

  • 你不能合法地读写任何东西似乎有点奇怪,然后跟着它只有所谓的POD类型可以在你正在尝试做的方式。。除非我遗漏了什么,否则答案似乎自相矛盾。
  • @NathanOliver 也许如果您将“任何事物”读作“任何旧事物”而不是“任何事物”。我试图澄清。
  • @NathanOliver 我知道我的答案有点含糊,但这是一个很难向初学者解释的话题,而且我最后一次尝试时根本不相信。短字符串优化没有帮助,因为有时它似乎可以工作。如果你知道一个好的副本,我很乐意放弃我的答案。
  • @john 我搜索了 POD 类型并尝试使用 char 数组而不是字符串,并且它有效。谢谢!
  • @am_rendra9 这是一种选择。我很高兴我的回答有所帮助。可以读取和写入字符串,但不能一步完成。例如。你可以先写字符串的长度,然后再写字符串的字符。读取时先读取长度,然后构造那个长度的字符串,最后将字符读入新构造的字符串中。
猜你喜欢
  • 2015-08-06
  • 2018-01-08
  • 2020-03-06
  • 2018-09-18
  • 2013-03-20
  • 1970-01-01
  • 2015-06-08
  • 1970-01-01
相关资源
最近更新 更多