Попытка прочитать текстовый файл в массив структур в C ++ - PullRequest
2 голосов
/ 02 апреля 2019

Во-первых, я использую DEVC ++, моя цель этого кода состоит в том, чтобы иметь возможность читать текстовый файл в массив структур. Мой текстовый файл написан так: animalName: animalType: RegistrationNo:. проблемно

Моя проблема с приведенным ниже кодом заключается в том, что кажется, что цикл while выполняется только один раз.

Я искал похожий код, но он использует to_string () и стои, но я не думаю, что 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 Ответ

3 голосов
/ 02 апреля 2019

Вы неправильно используете оператор запятую .

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, а затем для преобразования string в целое число с std::stoi.

Документация по 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++;
}

Еще лучший подход - сделать перегрузку оператора >> для Animal, потому что это позволяет вам написать основной цикл, который выглядит как

while (infile>> ani[i])
{ 
    i++;
}

И это так просто, что все радуются. См. Каковы основные правила и идиомы для перегрузки операторов? для получения информации о написании оператора >> и более общих соображений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...