C++ 用于循环和输入数据?

C++ 用于循环和输入数据?,c++,file,loops,input,for-loop,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;

我试图弄明白如何制定一个小的清单计划,但我始终无法弄明白为什么它不起作用

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


在一行中重复不同的书籍/CD等,所有内容都没有空格。应该是下一个。

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

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的方法进行类型解析。

添加一点检查:

 if (!invfile.is_open()) {
  cout<<"file open failed";
  exit(1);
 }
这样,你就不需要像现在这样到处复制你的输入文件- 您是按特定顺序读取的,因此您的输入文件应该具有相同的顺序和所需的输入数量


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

如果我这样做,我想我会将其结构完全不同

首先,我要重载操作符>>以获取记录:

然后我会使用std::vector而不是数组-它更不容易出错

要读取数据,我会使用std::istream_迭代器,可能会将它们提供给向量的构造函数:


在这两者之间,即在创建文件之后,但在向量插入错误处理之前,大致按照@Tom Kerr建议的顺序-检查is_open、bad、eof等,以确定在尝试打开文件时是否出现任何错误。

!文件?据我所知,当它打开的时候,它会启动cout。如果文件已成功打开,is_open返回true。正确。is_open在实际打开时返回true。因此,if语句将在文件打开时打印文件打开失败。正确吗?在这种情况下,该文件正在工作,但没有输出我需要的文件。只需编辑并放入.dat文件。它基本上是一行一行的,没有空格。所以不需要拼接。我把支票放进去了,但还是什么也没出来。这有点让我不知所措。。。我真的不知道该怎么办。这不是为学校准备的,所以我不想让它工作,我想知道为什么它不工作。@Nogg:我应该补充一点:我想我应该提供一个我知道存在的文件副本的完整绝对路径。这比将副本分散在各处并希望找到其中一个副本更能保证打开文件。@Nogg:只需给出文件的完整路径即可。例如,在Linux上,它类似于/usr/me/projects/inventory/inventory.dat。在Windows上,可能更像:C:\\projects\\inventory\\inventory.dat。如果在Windows上使用反斜杠,则需要将每个斜杠加倍。虽然它们没有经常使用,但如果您愿意,可以在Windows上使用普通斜杠。在这种情况下,您不需要像反斜杠一样将它们加倍。
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::ifstream invfile("inventory.dat");

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