背景故事: 我正在做一个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;
}
答案 0 :(得分:1)
我不确定这个网站的家庭作业政策是什么;但我认为只给你提示而不是答案是恰当的。
观察:您没有检查对该流的任何调用,因此在说出inventory.write()
之后,您不会检查写入是否成功。您可以通过任何 state 函数执行此操作,即:inventory.good()
。检测文件访问失败的位置将帮助您识别问题。
如果没有文件(因此创建了文件)并输入了23号记录,会发生什么?也就是说,如果文件大小为0,您认为调用inventory.seekg(23 * sizeof (InventoryItem))
会发生什么。
如果这看起来很神秘:想想在预先存在的文件和新创建的文件上进行此调用之间的区别。我相信一旦你意识到这一重大差异,解决方案就会很明确。
如果您正在努力将错误检查代码如上所述,这将有助于您进行调查。
祝你好运。
答案 1 :(得分:0)
也许你需要冲洗fstream(库存)?
答案 2 :(得分:0)
也许你应该致电
inventory.close(); //?
提交更改