在c ++中创建的二进制文件,但在运行后删除了内容

时间:2011-03-19 18:15:29

标签: c++ file-io binary fstream

背景故事: 我正在做一个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;
}

3 个答案:

答案 0 :(得分:1)

我不确定这个网站的家庭作业政策是什么;但我认为只给你提示而不是答案是恰当的。

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

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

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

如果您正在努力将错误检查代码如上所述,这将有助于您进行调查。

祝你好运。

答案 1 :(得分:0)

也许你需要冲洗fstream(库存)?

答案 2 :(得分:0)

也许你应该致电

inventory.close(); //?

提交更改