尝试将文本文件读入C ++中的结构数组

时间:2019-04-02 04:04:47

标签: c++ arrays struct

首先,我正在使用DEVC ++,此代码的目标是能够将文本文件读取为结构数组。我的文本文件是这样写的: animalName:animalType:RegistrationNo:ProblemNo。

我与下面的代码有关的问题是,它似乎只运行一次while循环。

我查找了类似的代码,但是它使用了to_string()和stoi,但是我不认为DEVC ++运行C ++ 11,所以我想知道是否可以轻松地修复现有代码,或者是否还有另一种方法可以完成阅读由字符串和整数组成的文本文件

#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#define MAX 100
using namespace std;

struct Animal
{
   string animalName;
   string animalType;
   int Registration;
   int Problem;
};

int main()
{
   Animal ani[MAX];
   ifstream infile;
   int i = 0;

   infile.open("Animals.txt");
   if (!infile) {
       cout << "Unable to open file";
       exit(1);
   }

   int count = 0;
   while (infile.good()) {
       getline(infile, ani[i].animalName, ':');
       getline(infile, ani[i].animalType, ':');
       infile >> ani[i].Registration, ':';
       infile >> ani[i].Problem, '.';

       count++;
       i++;
   }

   infile.close();
   for (int i = 0; i < count; i++) {
       cout << ani[i].animalName << " ";
   }
   for (int i = 0; i < count; i++) {
       cout << ani[i].animalType << " ";
   }
   for (int i = 0; i < count; i++) {
       cout << ani[i].Registration << " ";
   }
   for (int i = 0; i < count; i++) {
       cout << ani[i].Problem<< " ";
   }

   return 0;
}

1 个答案:

答案 0 :(得分:3)

您滥用comma operator

infile >> ani[i].Registration, ':';` 

不读取并丢弃':',导致流血的死亡……对不起。

时导致解析错误
infile >> ani[i].Problem

尝试将':'转换为整数。这会使infile进入失败状态,

while (infile.good())

发现infile不好,并退出循环。

您将不得不按照

std::string temp;
std::getline(infile, temp, ':');
ani[i].Registration = std::stoi(temp);

将直到':'分隔符的流读入std::string,然后用stringstd::stoi转换为整数。

Documentation on std::stoi

这是大部分错误。但是...

while (infile.good())

在读取流之前测试流是否良好。这样一来,在使用失败结果之前,如果不进行任何测试,则流在读取时完全失败。

while (getline(infile, ani[i].animalName, ':') &&
       getline(infile, ani[i].animalType, ':') &&
       getline(infile, temp1, ':') &&
       getline(infile, temp2, '.'))
{ // only goes into loop if everything was read
  // may also have to eliminate a newline here
    ani[i].Registration = std::stoi(temp1);
    ani[i].Problem = std::stoi(temp2); //exception if bad
    i++;
}

一种更好的方法是使>>的{​​{1}}运算符重载,因为这样您就可以编写一个看起来像这样的主循环

Animal

这是如此简单,所有人都很高兴。有关编写while (infile>> ani[i]) { i++; } 运算符的信息和更多常识,请参见What are the basic rules and idioms for operator overloading?