整个问题:
问题3您是五金店的所有者,需要保留一份库存,告诉您有哪些不同的工具,每个工具有多少以及每个工具的成本 . 编写一个程序,将随机访问文件“hardware.dat”初始化为100个空记录,让您输入有关每个工具的数据,使您能够列出所有工具,让您删除不再拥有的工具的记录并允许您更新文件中的任何信息 . 工具识别号应为记录号 . 使用以下信息启动文件 .
My Code :
int question_3()
{
cout << "Question 3" << endl;
fstream hardware;
hardware.open("hardware.dat" , ios::binary | ios::out);
//Create 100 blank objects---------------------------------------------------------------
if (!hardware)
{
cerr << "File could not be opened." << endl;
exit(1);
}
HardwareData myHardwareData;
for (int counter = 1; counter <= 100; counter++)
{
hardware.write(reinterpret_cast< const char * >(&myHardwareData), sizeof(HardwareData));
}
cout << "Successfully create 100 blank objects and write them into the file." << endl;
hardware.close();
hardware.open("hardware.dat" , ios::binary | ios::out | ios::in);
//Write data-----------------------------------------------------------------------------
int record;
int quantity;
float cost;
string tool_name;
cout << endl;
cout << "Enter record number (1 to 100, 0 to end input) : ";
cin >> record;
while (record != 0)
{
cin.sync();
cout << "Enter tool name : "; getline(cin, tool_name);
cout << "Enter quantity : "; cin >> quantity;
cout << "Enter cost : "; cin >> cost;
myHardwareData.setRecord(record);
myHardwareData.setToolName(tool_name);
myHardwareData.setQuantity(quantity);
myHardwareData.setCost(cost);
hardware.seekp((myHardwareData.getRecord() - 1) * sizeof(HardwareData));
hardware.write(reinterpret_cast<const char *>(&myHardwareData), sizeof(HardwareData));
cout << endl
<< "Enter record number (1 to 100, 0 to end input) : ";
cin >> record;
}
cout << "Successfully write all input data into the file." << endl;
//Read data----------------------------------------------------------------------------
cout << endl;
outputDataLineHead();
hardware.read(reinterpret_cast<char *>(&myHardwareData), sizeof(HardwareData));
int counter = 0;
cout << setprecision(2) << fixed;
while (hardware && !hardware.eof())
{
if (myHardwareData.getRecord() != 0)
outputDataLine(cout, myHardwareData);
hardware.seekp(counter++ * sizeof(HardwareData));
hardware.read(reinterpret_cast<char *>(&myHardwareData), sizeof(HardwareData));
}
return 0;
}
//Function for showing data in line form.-----------------------------------------------
void outputDataLineHead()
{
cout << left << setw(17) << "Record No."
<< left << setw(17) << "Tool Name"
<< left << setw(17) << "Quantity"
<< left << setw(17) << "Cost" << endl;
}
void outputDataLine(ostream &output, const HardwareData &Object_in_file)
{
output << left << setw(17) << Object_in_file.getRecord()
<< left << setw(17) << Object_in_file.getToolName()
<< left << setw(17) << Object_in_file.getQuantity()
<< left << setw(17) << Object_in_file.getCost() << endl;
}
HardwareData.h :
#ifndef HAREWAREDATA_H
#define HAREWAREDATA_H
#include <iostream>
using std::string;
class HardwareData
{
public :
HardwareData(string name = "", int recd = 0, int qutity = 0, float cot = 0.0)
{
setToolName(name);
setRecord(recd);
setQuantity(qutity);
setCost(cot);
}
void setToolName(string name)
{
const char *nameValue = name.data();
int length = 0;
length = (length < 15 ? length : 14);
strncpy(tool_name, nameValue, length);
tool_name[length] = '\n';
}
string getToolName() const
{
return tool_name;
}
void setRecord(int recd)
{
record = recd;
}
int getRecord() const
{
return record;
}
void setQuantity(int qutity)
{
quantity = qutity;
}
int getQuantity() const
{
return quantity;
}
void setCost(float cot)
{
cost = cot;
}
float getCost() const
{
return cost;
}
private :
char tool_name[15];
int record;
int quantity;
float cost;
};
#endif
我想显示如下数据:
Record No. Tool Name Quantity Cost
4 electric hammer 3 34.32
怎么做到这一点?
Thank you for your attention.
2 回答
我认为您的问题是在读取数据时..请检查您的变量是否得到正确的数据..您可以通过计算字符或尝试打印它们来检查 .
如果他们不正确 . 你可以使用我在下面使用的这样一个例子 .
首先,我更喜欢你像这个例子一样阅读你的行;
在这个例子中,我得到了面部的坐标 . 你应该改变参数..为了不读不需要数据
如果一切都很好 . 你应该检查一下
这里的核心问题是,您正在读取/写入
HardwareData
类型的对象的字节,而不是您应该创建插入器/提取器,以便您可以实现正确的I / O语义 . 例如:这两个声明分别用于插入器和提取器 . 输入应包括提取到
record
,tool_name
,quantity
和cost
数据成员;输出应该只是一个流插入,这是很容易实现的 .将格式化输入与未格式化输入混合时,通常存在问题,即残余换行禁止进一步输入 . 这似乎就是这样的情况:
在
cin >> record;
完成后,流中会有一个换行符 . 该换行符将使std::getline()
无法正常工作,因为std::getline()
只读取到换行符 .这里的修复是通过使用
std::ws
操纵器忽略这个新行:注意:我会更详细地讨论这个问题here .
但是不需要这种手动提取,因为我们已经为我们的类定义了插入器和提取器 . 所以真正需要的是以下内容:
要么
注意到我如何在
while
循环中检查0
的0
值 . 那是因为提取器通过将record
的0
值反映为无效输入来处理它 . 如果发生这种情况,它会设置流的流状态,从而允许自己从_2606120中弹出:如果发生这种情况:if((是>>记录)&&记录!= 0)
{
// ...
其他
{
is.setstate(标准::的ios_base :: failbit);
}
// ...
}
并将其余代码更改为:
std :: cout << std :: setprecision(2)<< std :: fixed;
而(硬件>> myHardwareData)
{
if(myHardwareData.getRecord()!= 0)
std :: cout << myHardwareData;
}
我真的不知道
seekp
是什么用的 . 如果您详细说明,那将真正帮助我更准确地调整我的代码以满足您的需求 .