C ++使用分隔符将文本文件读入struct数组

时间:2017-01-24 23:08:12

标签: c++ arrays struct

我正在尝试从与此类似的格式文本文件中读取数据:

knife, object, 0
bag, object, 15
kitchen, room, 400

进入由结构组成的数组。这是我到目前为止所做的,但它只读取第一个元素然后返回垃圾。

#include <iostream>
#include <fstream>
#include <string>


using namespace std;

struct itemlist
{
  string type;
  string selltype;
  int price;
  int diditsell=0;
};

int main()
{
  string filename;
  cout << "Please enter a file name. " << endl;
  cin >> filename;

  ifstream in(filename);
  itemlist c[100];
  for (int i=0;i<100;i++)
  {
      in >> c[i].type >> c[i].selltype >> c[i].price;
      cout << c[i].type << endl;
      cout << c[i].selltype << endl;
      cout << c[i].price << endl;
  }
}

我试图找到特别适合我尝试做的例子,但实施它们并没有解决问题。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

可见问题的症结在于

 for (int i=0;i<100;i++)

将打印出整个100个元素数组,无论文件中是否有数据要加载到数组中。

可能是最简单的方法is with a std::vector。它是一个动态大小的数组。当你添加它它变得更大,所以你不必担心它溢出。我们最后会回复它。

接下来要做的就是确保您已成功读取文件。 Streams can be tested to see if they are valid

if (in)
{
    cout << "in is good!" << endl;
}

并且>>运算符返回对流的引用,以便您可以

if (in >> data)
{
    cout << "data is good!" << endl;
}

如果在读取数据后流仍然良好,您知道至少该文件读取的数据类型正确或可以转换为正确的类型。您应该在阅读之后检查读取的值,以确保用户没有输入错误或者让他们不知所措。如果你想循环很多东西,比如一个文件,你最终得到这样的东西:

while (in >> c[i].type >> c[i].selltype >> c[i].price)

如果任何读取失败,则在测试时流将返回false并且循环将退出。

查看源数据,您可以使用空格和逗号进行处理。 >>只知道如何处理空格,除非你要做很多额外的工作。您将阅读的内容是

knife,
object,
0

我们不想要逗号。幸运的是,它是最后一个角色,因此处理它很容易。一个C++11 std::string can be used like a stack,您只需弹出不需要的字符:

c[i].type.pop_back();
c[i].selltype.pop_back();

总之,这给了我们一个看起来像

的循环
ifstream in(filename);
itemlist c[100];
int i = 0;
while (in >> c[i].type >> c[i].selltype >> c[i].price)
{
    c[i].type.pop_back();
    c[i].selltype.pop_back();
    cout << c[i].type << endl;
    cout << c[i].selltype << endl;
    cout << c[i].price << endl;
    i++;
}

但是这可能会超出100元素数组的末尾,因此我们需要稍微更改while循环:

while (i < 100 && in >> c[i].type >> c[i].selltype >> c[i].price )

如果i大于或等于100,则i < 100大小写失败并且循环退出时甚至没有尝试in >> c[i].type >> c[i].selltype >> c[i].price并写入不存在的数组插槽。

请记住保持i的值,因为数组是愚蠢的。他们不知道自己有多饱。

但使用vector您不需要i来计算或跟踪它的充实程度,并且您不必担心会溢出阵列直到您从RAM中运行计算机。我们需要的是一个临时变量,可以阅读,我们很高兴。

vector<itemlist> c;
itemlist temp;
while (in >> temp.type >> temp.selltype >> temp.price)
{
    temp.type.pop_back();
    temp.selltype.pop_back();
    cout << temp.type << endl;
    cout << temp.selltype << endl;
    cout << temp.price << endl;
    c.push_back(temp);
}

答案 1 :(得分:0)

我遇到了同样的问题。 调试显示它正在读取第一个数组元素但跳过第二个元素并输出信息。从第一个元素。 通过使它读取第一个元素两次来解决这个问题。 例如见下文。

我还在播放器阵列中有其他输入。 在添加该行后,一切都很顺利。 我必须为我阅读的每个阵列都这样做。 我查看了它正在阅读的文本文件,当然 每个数组开始前都有一个空行。 我不知道编写该文件的程序为什么这样做。 我没有在数组前放一个空行。 注意:而不是让它读取第一个数组元素两次, 你可能会把它读成空白行。

 for (int i = 0; i < PLAYER; i++)
    {
    getline(teamRosterIn, playerName[i]);
    cout << playerName[i] << endl;
    getline(teamRosterIn, playerName[i]);
    cout << playerName[i] << endl;
    }