用于循环和输入数据

For loops and inputing data?

本文关键字:数据 输入 循环 用于      更新时间:2023-10-16

试图弄清楚如何制作一个小库存程序,但我一生都无法弄清楚为什么它不起作用。

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct record
{
    int item_id;
    string item_type;
    int item_price;
    int num_stock;
    string item_title;
    string item_author;
    int year_published;
};
void read_all_records(record records[]);
const int max_array = 100;
int main()
{
    record records[max_array];
    read_all_records(records);
    cout << records[2].item_author;
    return 0;
}
void read_all_records(record records[])
{
    ifstream invfile;
    invfile.open("inventory.dat"); 
    int slot = 0;
    for (int count = 0; count<max_array; count++);
    {
        invfile >> records[slot].item_id >> records[slot].item_type >> records[slot].item_price >> records[slot].num_stock >> records[slot].item_title >> records[slot].item_author >> records[slot].year_published;
        slot++;
    }
    invfile.close();
}

我正在测试它,让它打印记录作者的第二项。当我运行它时,它根本不显示作者的名字。.dat文件几乎位于项目所在的每个文件夹中(我忘了它需要在哪个文件夹中),所以它就在那里。问题不在于文件不起作用。这是数组没有打印出任何内容。我的inv文件基本上是:

123456书69.9916标题等etc

并为不同的书/ccd等重复,所有这些都在一行,没有空格。应该是下一个。

您应该检查文件是否打开。

invfile.open("inventory.dat"); 
if (!invfile.is_open())
  throw std::runtime_error("couldn't open inventory file");

您应该检查文件读取是否正常,并在到达文件末尾时中断。

invfile >> records[slot].item_id >> records[slot].item_type ...
if (invfile.bad())
  throw std::runtime_error("file handling didn't work");
if (invfile.eof())
  break;

您可能希望一次读取每个记录,因为从这段代码中还不清楚C++流应该如何区分每个字段。

通常,您希望使用std::getline,根据您对字段的定界方式对其进行拆分,然后使用类似boost::lexical_cast的方法来进行类型解析。

如果我这样做,我想我的结构会有很大的不同。

首先,我会为record:过载operator>>

std::istream &operator>>(std::istream &is, record &r) { 
    // code about like you had in `read_all_records` to read a single `record`
    // but be sure to return the `stream` when you're done reading from it.
}

然后我会使用std::vector<record>而不是数组——它不太容易出错。

为了读取数据,我会使用std::istream_iterators,可能会将它们提供给vector<record>:的构造函数

std::ifstream invfile("inventory.dat");
std::vector<record> records((std::istream_iterator<record>(invfile)),
                             std::istream_iterator<record>());

在这两者之间(即,在创建文件之后,但在向量之前),您可以插入错误处理,大致按照@Tom Kerr建议的顺序——检查is_open()bad()eof()等,以找出试图打开文件时出现的问题(如果有)。

添加一个小检查:

 if (!invfile.is_open()) {
  cout<<"file open failed";
  exit(1);
 }

因此,您不需要像现在这样到处复制输入文件;-)您按照特定的顺序进行读取,因此您的输入文件应该具有相同的顺序和所需的输入数量。

您正在打印结构记录的第三个元素。所以你应该至少有3个记录。我看不出你的代码有什么问题。如果您可以发布您的示例输入文件,这会容易得多。