【问题标题】:Reading duplicated objects on files C++读取文件 C++ 上的重复对象
【发布时间】:2020-07-22 14:34:03
【问题描述】:

我在用 C++ 为我的程序创建文件系统时遇到了一些问题。好吧,我正在创建一个新学生,如果他是我在保存文件和关闭程序之前创建的最后一个对象,它就会被复制。例如,两个对象:Daniel、Paul。它只显示最后一个重复的:Daniel、PaulPaul - 在 file.txt 中。

这是我的一些代码:

文件阅读:

ifstream file;
file.open("file.txt");

while (1)
{
Student *p = new Student();
    if (file.eof() || file.bad() || file.fail())
    {
        break;
    }

    getline(file, ALLTHESTRINGVARIABLES);
    p->STRINGVARIABLES = ALLTHESTRINGVARIABLES;

    file >> ANOTHERVARIABLES;
    p->NOTSTRINGVARIABLES = ANOTHERVARIABLES;

    students.push_back(p);
}
file.close();

文件写入:

   fstream file;
   file.open("file.txt", ios::out | ios::trunc);
      for(unsigned int i = 0; i < students.size(); i++){
         file << students[i]->VARIABLEEXAMPLE << endl;
      }
   file.close();

谢谢!!

【问题讨论】:

  • 无关:不要使用new。只需将其设为Student p; 并将其设为std::vector&lt;Student&gt; students; 即可避免手动内存管理。
  • 显示Studentfile.txt 的示例。创建minimal reproducible example
  • @Ted Lyngmo 你可能是对的,但由于学生容器包含指针,我们需要分配(unique_ptr 或 shared_ptr 可能?)。如果没有完整的代码和实际用例,就无法判断。也就是说,是否有充分的理由使用指针容器?我们无法从我们得到的东西中分辨出来:(
  • 好的,但是为什么不按照我的建议制作学生容器呢?是否使用了动态调度?

标签: c++ file oop fstream archive


【解决方案1】:

eof()、bad()、fail() 只有在尝试从文件中读取一些字节但没有成功时才会返回 true。所以,把 if 验证放在 getline() 之后。

然后在此之后创建 Student 的新实例以避免内存泄漏。

像这样:

while (1)
{
    getline(file, ALLTHESTRINGVARIABLES);
    if (file.eof() || file.bad() || file.fail())
        break;

    Student *p = new Student();
    p->STRINGVARIABLES = ALLTHESTRINGVARIABLES;

    file >> ANOTHERVARIABLES;
    p->NOTSTRINGVARIABLES = ANOTHERVARIABLES;

    students.push_back(p);
}

【讨论】:

    【解决方案2】:

    eof() 不会返回true,直到您实际尝试读取文件末尾之外的内容,这就是您看到最后一行重复的原因。 getline 将失败,ALLTHESTRINGVARIABLES 将包含最新成功读取的值。您应该在存储新的Student 之前检查提取是否确实成功。

    由于您混合了未格式化和格式化的输入,您还应该从流中删除换行符(或用于分隔记录的任何字符)。

    将循环改为:

    if (std::ifstream file("file.txt"); file)
    {
        while (std::getline(file, ALLTHESTRINGVARIABLES) >> ANOTHERVARIABLES)
        {
            // remove the newline or whatever whitespace char you use as record separator
            file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    
            Student *p = new Student;
            p->STRINGVARIABLES = ALLTHESTRINGVARIABLES;
            p->NOTSTRINGVARIABLES = ANOTHERVARIABLES;
            students.push_back(p);
        }
    }
    

    我还建议您不要存储指针(除非您使用动态分派),而是将实际的 Student 对象存储在 std::vector&lt;Student&gt; 中。如果使用动态调度,则将std::unique_ptr&lt;Student&gt; 存储在vector 中。

    【讨论】:

    • 特德,谢谢你的帮助!前面回复的程序员 Derzu 收到了复选标记,因为这也是一个解决方案。
    • @DanielCassianoChaves 不客气!请注意,如果在使用其他答案时file &gt;&gt; ANOTHERVARIABLES; 失败,您将在vector 中添加一个损坏的Student。另外,如果不删除记录分隔符,我看不到它是如何工作的。
    猜你喜欢
    • 1970-01-01
    • 2018-08-29
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 2015-05-19
    • 2020-02-21
    • 2015-06-30
    • 1970-01-01
    相关资源
    最近更新 更多