[英]C++ Random Access Files
这是我第一次在C ++中尝试随机访问文件,但是我之前在Java中尝试过它,但无法在C ++中使用它。 我的想法是要创建100个空记录,然后将记录存储在文件中的特定记录编号处。 这是我的代码,我尽可能地简化了代码。
我这里有一个名为Tool的结构:
struct Tool {
int number;
char name[20];
int quantity;
double cost;
};
这是我的主要功能:
fstream outFile;
outFile.open("inventory.dat");
// Create 100 empty tool records
Tool tool;
tool.number = 0;
tool.name[0] = '\0';
tool.quantity = 0;
tool.cost = 0;
for (int i = 0; i < 100; i++) {
outFile.write(reinterpret_cast<char *>(&tool.number), sizeof(int));
outFile.write(tool.name, sizeof(char)* 20);
outFile.write(reinterpret_cast<char *>(&tool.quantity), sizeof(int));
outFile.write(reinterpret_cast<char *>(&tool.cost), sizeof(double));
}
// Insert A tool record
Tool t;
t.number = 3;
t.quantity = 7;
t.cost = 57;
strcpy(tool.name, "Electric Sander");
outFile.seekp((tool.number - 1) * sizeof(Tool));
outFile.write(reinterpret_cast<char *>(&tool.number), sizeof(int));
outFile.write(tool.name, sizeof(char)* 20);
outFile.write(reinterpret_cast<char *>(&tool.quantity), sizeof(int));
outFile.write(reinterpret_cast<char *>(&tool.cost), sizeof(double));
outFile.close();
我初始化100条空记录的部分工作正常(假设我们要注释代码的插入部分。
但是,当执行插入部分时,我的程序会生成4 GB的数据。 我不确定发生了什么。 我感谢任何帮助。 提前致谢。
您可以编写该结构的全部内容
outFile.seekp(t.number*sizeof(Tool));
outFile.write(reinterpret_cast<char *>(&tool),sizeof(Tool));
不要忘记告诉编译器不要插入填充
#ifdef MSVC
#pragma pack(push,1)
#endif
struct Tool {
int number;
char name[20];
int quantity;
double cost;
#ifdef GCC
}__attribute__((packed));
#else
};
#endif
#ifdef MSVC
#pragma pack(pop)
#endif
资料来源:
https://codereview.stackexchange.com/questions/26344/writing-reading-data-structure-to-a-file-using-c
https://stackoverflow.com/a/18654265/194717
我们宝贵的成员的意见。
您使用了在最后一部分中表示t
tool
。 尤其是:
outFile.seekp((tool.number - 1) * sizeof(Tool));
应该:
outFile.seekp((t.number - 1) * sizeof(Tool));
以及所有其他tool.
末尾的字段(假设您要使用t
)。 tool.number
为0,因此tool.number - 1
为-1。 如果pos_type
是无符号且为32位,则包装的值会将您请求的位置放在4GB左右。
同样,托马斯·马修斯(Thomas Matthews)在其评论中提出的对准点和托尼(Tony)在其回答中详述的点对于确保文件中的数据正确也是很重要的。
在有关二进制模式的注释中提到的Deduplicator和Galik点对于确保正确写入数据也很重要。
这是一个替代方案:
struct Tool
{
int number;
char name[20];
int quantity;
double cost;
void binary_write(std::ostream& out) const
{
out.write((char *) &number, sizeof(number));
out.write((char *) &name[0], sizeof(name);
out.write((char *) &quantity, sizeof(quantity));
out.write((char *) &cost, sizeof(cost));
}
void binary_read(std::istream& inp)
{
inp.read((char *) &number, sizeof(number));
inp.read((char *) &name[0], sizeof(name);
inp.read((char *) &quantity, sizeof(quantity));
inp.read((char *) &cost, sizeof(cost));
}
size_t binary_size(void) const
{
return sizeof(number) + sizeof(name)
+ sizeof(quantity) + sizeof(cost);
}
};
int main(void)
{
std::ofstream outfile("test.dat", ios::binary);
if (!outfile)
{
cerr << "Error opening test.dat\n";
return 1;
}
Tool t;
for (unsigned int i = 0; i < 100; ++i)
{
t.binary_write(outfile);
}
outfile.close();
std::ifstream in_file("test.dat", ios::binary)
if (!in_file)
{
cerr << "Error opening test.dat for reading\n";
return 2;
}
in_file.seekg(10 * t.binary_size(), ios::beg);
t.binary_read(in_file);
return 0;
}
这里的概念是将读写功能放入对象中,因为该对象了解其成员,并且您可以从其他对象中隐藏数据(这是一件好事)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.