C++ 从文件(C+;+;,fstream)读取数据不正确

C++ 从文件(C+;+;,fstream)读取数据不正确,c++,file,fstream,ifstream,readfile,C++,File,Fstream,Ifstream,Readfile,整个问题: 问题3 你是一家五金店的老板,需要保存一份清单,可以告诉你你有哪些不同的工具,手头有多少,以及每种工具的成本。编写一个程序,将随机访问文件“hardware.dat”初始化为100条空记录,让您输入有关每个工具的数据,让您列出所有工具,让您删除不再拥有的工具的记录,并让您更新文件中的任何信息。工具识别号应为记录号。使用以下信息启动文件 我的代码: int question_3() { cout << "Question 3" << endl;

整个问题:

问题3

你是一家五金店的老板,需要保存一份清单,可以告诉你你有哪些不同的工具,手头有多少,以及每种工具的成本。编写一个程序,将随机访问文件“hardware.dat”初始化为100条空记录,让您输入有关每个工具的数据,让您列出所有工具,让您删除不再拥有的工具的记录,并让您更新文件中的任何信息。工具识别号应为记录号。使用以下信息启动文件


我的代码:

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;
}
#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
如何做到这一点



感谢您的关注。

我认为您的问题在于阅读数据时。。请检查变量是否获得正确的数据。。您可以通过计数字符来检查这一点,或者尝试打印它们

如果他们不正确。你可以用我在下面的例子

首先,我希望你像这样读你的台词

在这个例子中,我得到了面的坐标。您应该更改参数。。为了不读取不需要的数据

std::string str;
    while(std::getline(in, str))
    {
        sscanf(str.c_str(), "%d %f %f", &fiducial.number, &fiducial.x, &fiducial.y);

        coord_Num[fiducial.number] = fiducial.get_number();
        coord_X[fiducial.number] = fiducial.get_x();
        coord_Y[fiducial.number] = fiducial.get_y();

    }
如果一切看起来都很好。你应该检查一下

void outputDataLine(ostream &output, const HardwareData &Object_in_file)

这里的核心问题是,您正在向类型为
HardwareData
的对象读写字节,而应该创建插入器/提取器,以便实现正确的I/O语义。例如:

cin>>记录完成后,流中会留下一个换行符。该换行符将停止
std::getline()
正常工作,因为
std::getline()
只在换行符之前读取

这里的修复方法是使用
std::ws
操纵器忽略这一新行:

注:我将更详细地讨论这一点

但是不需要手动提取,因为我们已经为类定义了插入器和提取器。因此,真正需要的是以下内容:


其余代码将更改为:

std::cout>myHardwareData;
标准::cout myHardwareData)
{
如果(myHardwareData.getRecord()!=0)

std::你能解释一下你的问题吗?这有点帮助。仅供参考,你还没有创建100个对象;你创建了1个对象并向其写入了100次。除非工具名是固定大小的普通数组,否则你不能这样编写类实例。你需要一个序列化规则。这里有无数关于这个问题的答案。工具名是st或以字符形式:{char tool_name[15];}创建一个。
void outputDataLine(ostream &output, const HardwareData &Object_in_file)
// Inside HardwareData class
friend std::ostream& operator<<(std::ostream&, const HardwareData&);
friend std::istream& operator>>(std::istream&,       HardwareData&);
cin >> record;                                                             /*
^^^^^^^^^^^^^^                                                             */

while (record != 0)
{
    cin.sync();
    cout << "Enter tool name : ";           getline(cin, tool_name);
    //                                      ^^^^^^^^^^^^^^^^^^^^^^^^

    // ...
}
std::getline(std::cin >> std::ws, tool_name);
//           ^^^^^^^^^^^^^^^^^^^
while (std::cin >> myHardwareData)
{
    hardware << myHardwareData;
}
std::copy(std::istream_iterator<HardwareData>(std::cin),
          std::istream_iterator<HardwareData>(),
          std::ostream_iterator<HardwareData>(hardware));
std::istream& operator>>(std::istream& is, HardwareData& hd)
{
    cout << "Enter record number (1 to 100, 0 to end input) : ";

    if ((is >> record) && record != 0)
    {
          // ...
    } else
    {
        is.setstate(std::ios_base::failbit);
    }
    // ...
}
std::cout << myHardwareData;
hardware >> myHardwareData;

std::cout << std::setprecision(2) << std::fixed;
while (hardware >> myHardwareData)
{
    if (myHardwareData.getRecord() != 0)
        std::cout << myHardwareData;
}