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

发布于 2024-10-24 02:15:40 字数 4290 浏览 3 评论 0原文

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

Backstory:
I'm doing a C++ school project. I need write a program that, among other things, creates a binary file if it doesn't already exist, allows the user to modify it, and saves the file so that it can be opened again and read or modified. I have written the main program separately, but I haven't been able to get the file input and output to work appropriately, so I have been experimenting with modifying some sample code from my textbook CD. Most of the textbook samples come with an existing .dat file that is supposed to be loaded, or only create, only write, or only read. However, our professor wants us to turn in the .cpp file without a .dat file. The program is supposed to generate the .dat file and allow for reading and writing. So, I don't have good examples to work from.

Main point:
Why does this program seem to create a file, write to it and read from it, and then when it closes, I go to the directory where the .dat file is stored, and the file is blank (says 0 bytes)? How can I get the content to stay in the file when I close? Is it even being properly created in the first place?

(By the way, I know that after the prompt to enter data, it displays garbage. I just set that up to see if there was content in the record before data input.)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

记忆で 2024-10-31 02:15:40

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

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

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

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

如果您正在努力输入上面提到的错误检查代码,这将有助于指导您的调查。

祝你好运。

I'm not sure what the policy on homework on this site is; but I feel it is appropriate to only give you hints and not an answer.

Observation: you do not check any of your calls to the stream, so after say inventory.write() you do not check that the write was successful. You may do this via any of the state functions, ie: inventory.good(). Detecting where file access fails is going to help you identify your problem.

What happens if there is no file (so it is created) and I enter record number 23? That is, if the file size is 0 what do you think will happen with the call inventory.seekg(23 * sizeof (InventoryItem)).

If this seems cryptic: think about the difference between making this call on a pre-existing file, and a newly created file. I believe once you recognize the significant difference, the solution will be clear.

If you are struggling put in error checking code as mentioned above, this will help direct your investigation.

Good luck.

物价感观 2024-10-31 02:15:40

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

Maybe you need to flush the fstream (inventory)?

时间海 2024-10-31 02:15:40

也许你应该调用

inventory.close(); //?

提交更改

Maybe you should call

inventory.close(); //?

to commit the change

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文