【问题标题】:binary file created in c++ but content deleted after running用 C++ 创建的二进制文件,但运行后内容被删除
【发布时间】:2011-03-19 18:15:28
【问题描述】:

背景故事: 我正在做一个 C++ 学校项目。我需要编写一个程序,除其他外,如果它不存在,则创建一个二进制文件,允许用户修改它,并保存文件以便可以再次打开并读取或修改它。我已经单独编写了主程序,但是我无法让文件输入和输出正常工作,所以我一直在尝试修改我教科书 CD 中的一些示例代码。大多数教科书示例都带有一个现有的 .dat 文件,该文件应该被加载、或仅创建、仅写入或仅读取。但是,我们的教授希望我们在没有 .dat 文件的情况下上交 .cpp 文件。该程序应该生成 .dat 文件并允许读取和写入。所以,我没有很好的例子可供参考。

要点: 为什么这个程序似乎创建了一个文件,写入并从中读取,然后当它关闭时,我转到存储 .dat 文件的目录,该文件是空白的(说 0 字节)?关闭时如何让内容保留在文件中?它是否一开始就被正确创建了?

(对了,我知道提示输入数据后会显示垃圾,我只是设置一下,看看输入数据前记录中是否有内容。)

// This program allows the user to edit a specific record.
#include <iostream>
#include <fstream>
using namespace std;

const int DESC_SIZE = 31;  // Description size

// Declaration of InventoryItem structure
struct InventoryItem
{
   char desc[DESC_SIZE];
   int qty;
   double price;
};

int main()
{
   InventoryItem record;  // To hold an inventory record
   long recNum;           // To hold a record number
   long numBytes;

   fstream inventory;

   // Open the file in binary mode for input and output
    inventory.open("Inventory.dat",
                     /*ios::in | */ios::out | ios::binary);

   //file.open("Inventory.dat", ios::in | ios::out | ios::binary);
   if (!inventory.is_open())
   {
      cout << "Creating ...\n";
      // Create the file.
      inventory.open("Inventory.dat", ios::out);
      // Close the file.
      inventory.close();
      // Reopen the file for input and output.
      inventory.open("Inventory.dat", ios::in | ios::out | ios::binary);
   }
   inventory.seekg(0L, ios::end);
   numBytes = inventory.tellg();
   cout << "After opening: The file has " << numBytes << " bytes." << endl;

   // Get the record number of the desired record.
   cout << "Which record do you want to edit? ";
   cin >> recNum;

   // Move to the record and read it.
   inventory.seekg(recNum * sizeof(record), ios::beg);
   inventory.read(reinterpret_cast<char *>(&record),
                 sizeof(record));

   // Display the record contents.
   cout << "Description: ";
   cout << record.desc << endl;
   cout << "Quantity: ";
   cout << record.qty << endl;
   cout << "Price: ";
   cout << record.price << endl;

   // Get the new record data.
   cout << "Enter the new data:\n";
   cout << "Description: ";
   cin.ignore();
   cin.getline(record.desc, DESC_SIZE);
   cout << "Quantity: ";
   cin >> record.qty;
   cout << "Price: ";
   cin >> record.price;

   // Move back to the beginning of this record's position.
   inventory.seekp(recNum * sizeof(record), ios::beg);

   // Write the new record over the current record.
   inventory.write(reinterpret_cast<char *>(&record),
                  sizeof(record));


   inventory.seekg(0L, ios::end);
   numBytes = inventory.tellg();
   cout << "The file has " << numBytes << " bytes.";

 // Move to the record and read it.
   inventory.seekg(recNum * sizeof(record), ios::beg);
   inventory.read(reinterpret_cast<char *>(&record),
                 sizeof(record));

   // Display the record contents.
   cout << "Description: ";
   cout << record.desc << endl;
   cout << "Quantity: ";
   cout << record.qty << endl;
   cout << "Price: ";
   cout << record.price << endl;

   inventory.seekg(0L, ios::end);
   numBytes = inventory.tellg();
   cout << "The file has " << numBytes << " bytes.";

   // Close the file.
   inventory.close();


    //Try opening the file again.
    inventory.open("Inventory.dat",
                     ios::in | /*ios::out |*/ ios::binary);

 // Move to the record and read it.
   inventory.seekg(recNum * sizeof(record), ios::beg);
   inventory.read(reinterpret_cast<char *>(&record),
                 sizeof(record));

   // Display the record contents.
   cout << "Description: ";
   cout << record.desc << endl;
   cout << "Quantity: ";
   cout << record.qty << endl;
   cout << "Price: ";
   cout << record.price << endl;

   inventory.seekg(0L, ios::end);
   numBytes = inventory.tellg();
   cout << "The file has " << numBytes << " bytes.";


   return 0;
}

【问题讨论】:

  • 我应该补充一点,我尝试了使用和不使用 ios::in |注释掉了。我还尝试了一行而不是单独的打开函数:fstream inventory("Inventory.dat", /*ios::in | */ios::out | ios::binary);

标签: c++ file-io binary fstream


【解决方案1】:

我不确定这个网站上的家庭作业政策是什么;但我觉得只给你提示而不给你答案是合适的。

观察:你没有检查你对流的任何调用,所以在说inventory.write()之后你没有检查写入是否成功。您可以通过任何 state 函数执行此操作,即:inventory.good()。检测文件访问失败的位置将帮助您确定问题。

如果没有文件(因此已创建)并且我输入记录号 23,会发生什么情况?也就是说,如果文件大小为 0,您认为调用 inventory.seekg(23 * sizeof (InventoryItem)) 会发生什么。

如果这看起来很神秘:想想在预先存在的文件和新创建的文件上进行此调用之间的区别。我相信,一旦您认识到显着差异,解决方案就会很清楚。

如果您在上面提到的错误检查代码中遇到困难,这将有助于指导您的调查。

祝你好运。

【讨论】:

【解决方案2】:

也许您需要刷新 fstream(库存)?

【讨论】:

  • 好吧,我的教科书没有提到这点。我现在会在网上查一下,但如果不是很明显,请告诉我如何以及在哪里执行此操作。
【解决方案3】:

也许你应该打电话

库存.close(); //?

提交更改

【讨论】:

    猜你喜欢
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多