Не удается извлечь некоторые записи из текстового файла - PullRequest
1 голос
/ 16 марта 2012

Мне нужно извлекать и отображать записи из текстовых файлов, содержащих данные, каждый раз, когда выполняются некоторые условия. Проблема в том, что некоторые записи опускаются при извлечении их из текстового файла. Любая помощь будет оценена. Мой код ниже, написанный на Dev-C ++:

#include <iostream>
#include <conio.h>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <string>


using namespace std;

int main()
{
  char manufacturer[16], model[16], year[10];
  int miles,car_cost;
  char response, line[256];
  string field1, field2, field3;

  int   MilesText ,car_costText;
  ofstream OS ("usedcars.txt", ios::out);
  cout<<"for each car please enter :"<<endl;

  do
  {
    ofstream OS ("usedcars.txt", ios::app);

    cout<<"The manufacturer: ";
    cin.getline(manufacturer, 16);
    cout<<"The model: ";
    cin.getline(model, 16);
    cout<<"The year: ";
    cin.getline(year, 8);
    cout<<"The miles: ";
    cin>>miles;
    cin.ignore();
    cout<<"The cost of car $: ";
    cin>>car_cost;

    OS<<  manufacturer << setw(9) <<  model << setw(8) << year << setw(11) << miles << setw(8) << car_cost<<endl;
    cout<<"Do you want to continue?";
    cin>>response;
    cin.ignore();
  }
    while (response!='n');  
    OS.close();
    cout<<"-------------------------------------"<<endl;
    cout<<"the record found"<<endl;
    ifstream IS ("usedcars.txt", ios::in);
    while(!IS.eof())
    {   
      IS>>field1>>field2>>field3>>MilesText>>car_costText;
      if(MilesText<50000 && car_costText<9000)  //if the miles is less than 50000 and        the cost  is less than 9000 therefore...

     while(IS)
      {
       IS.getline(line, 256);
       if(IS)
       cout<<line<<endl;  //display the record from text file
     }
 }
IS.close();
getch();
return 0;  
}

********************** на выходе *********************** *********************

for each car please enter :
The manufacturer: Mitsubishi
The model: Lancer
The year: 2001
The miles: 12300
The cost of car $: 10780
Do you want to continue?y
The manufacturer: Ford
The model: Escape
The year: 2004
The miles: 150000
The cost of car $: 6200
Do you want to continue?y
The manufacturer: Audi
The model: A4
The year: 1999
The miles: 79000
The cost of car $: 11000
Do you want to continue?n

найдена запись

************************* в текстовом файле ******************* *******************

Mitsubishi   Lancer    2001      12300   10780
Ford   Escape    2004     150000    6200
Audi       A4    1999      79000   11000
Volvo      S80    1998      14000    7900

Ответы [ 2 ]

1 голос
/ 16 марта 2012

Вот несколько решений для вашей проблемы (часть, читающая входной файл), по крайней мере, если я понял, что вы хотите сделать правильно.Для меня он печатает все автомобили с пробегом <50000 и ценой ниже 9000 из входного файла. </p>

#include <sstream>
// rest of your code...

ifstream IS ("usedcars.txt", ios::in);
string lineTextfile;

while(IS)
{   
    getline(IS, lineTextfile); // read one line of input file

    istringstream parseLine(lineTextfile);

    parseLine>>field1>>field2>>field3>>MilesText>>car_costText; // parse individual elements of that line

    if(MilesText<50000 && car_costText<9000)  //if the miles is less than 50000 and        the cost  is less than 9000 therefore...
    {
        cout<<lineTextfile<<endl;  //display the record from text file
    }
}

IS.close();

Считывание данных из файлового потока и в потоке строк несколькоизбыточно, но это близко к примеру, с которого вы начали.


Если вы хотите использовать struct, вы можете использовать этот код для перегрузки потоковых операторов, например:

struct Car
{
    Car() : year(0), mileage(0), price(0) {};
    string manufacturer;
    string model;
    unsigned int year;
    unsigned int mileage;
    unsigned int price;
};

istream& operator>>(istream& is, Car& car)
{
    is >> car.manufacturer >> car.model >>  car.year >>  car.mileage >>  car.price;
    return is;
}

ostream& operator<<(ostream& os, const Car& car)
{
    os << car.manufacturer << " " << car.model << " " <<  car.year << " " <<  car.mileage << " " <<  car.price;
    return os;
}

bool IsFairPricedCar(const Car& car)
{
    return car.price < 9000 && car.mileage < 50000;
}

При таком определении struct возможно следующее:

ifstream IS ("usedcars.txt", ios::in);

while (IS)
{
    Car readCar;
    IS >> readCar;
    if(readCar.mileage < 50000 && readCar.price < 9000)
    {
        cout << readCar << endl;
    }
}

IS.close();

Альтернатива :

ifstream IS2 ("usedcars.txt", ios::in);

copy_if(istream_iterator<Car>(IS2), istream_iterator<Car>(),
    ostream_iterator<Car>(cout, "\n"), IsFairPricedCar);
0 голосов
/ 16 марта 2012

Кажется, вы прочитали свойства своего автомобиля и, если они совпадают, выведите следующую строку. Еще одна вещь, которую вы можете захотеть убедиться, что значения, которые вы пишете, не содержат пробелов. При записи значений вы, вероятно, должны убедиться, что между значениями есть хотя бы один пробел.

Я заметил, что вы используете eof() для условия в цикле: это определенно неправильно, и вы хотите использовать неявное преобразование в bool. Единственное использование eof() - подавление отчетов об ошибках, когда чтение не удалось, потому что вы достигли конца файла.

...