对于循环和输入数据?

时间:2012-03-28 01:01:52

标签: c++ file loops input for-loop

试图弄清楚如何制作一个小库存计划,我不能为生活弄清楚它为什么不起作用。

#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.99 16 标题 等等 等

并在一行中重复不同的书籍/ cds等,所有这些都没有空格。应该就在下一个。

3 个答案:

答案 0 :(得分:0)

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

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之类的东西来进行类型解析。

答案 1 :(得分:0)

添加一点检查:

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

这样,您就不需要像现在一样复制输入文件;-) 您正在按特定顺序阅读,因此您的输入文件应具有相同的顺序和所需的输入数量。

您正在打印struct记录的第3个元素。所以你应该至少有3条记录。我没看到你的代码有什么问题。如果您可以发布样本输入文件,那将会容易得多。

答案 2 :(得分:0)

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

首先,我为operator>>

重载record
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_iterator,可能会将它们提供给vector<record>的构造函数:

std::ifstream invfile("inventory.dat");

std::vector<record> records((std::istream_iterator<record>(invfile)),
                             std::istream_iterator<record>());

在这些之间(即,在创建文件之后,但在向量之前)是您插入错误处理的地方,大致按照@Tom Kerr建议的顺序 - 检查is_open(),{ {1}},bad()等,以确定在尝试打开文件时出现了什么(如果有的话)。