如何将数据从文件读取到类的数组中

How to read data from a file into an array of a class

本文关键字:数组 读取 文件 数据      更新时间:2023-10-16

此作业涉及制作一个程序,该程序将从文本文件中读取在汽车代理机构及其汽车( 汽车信息(中。

特别是我应该阅读汽车代理商名称,汽车代理邮政编码,然后是汽车的年份,制造,型号,其传感器及其可用性。

,由于它在文本文件中的外观'{''and}',我的传感器很难读取传感器。最大传感器也是3,但每辆车总是没有3个。

我已经创建了传感器,汽车和代理商课程。

输入文件(hightechagency.txt(:

Enterprise 89502
2014 Toyota Tacoma 115.12 {gps} 1
2012 Honda CRV 85.10 {camera lidar} 0
2011 Toyota Rav4 65.02 {} 0
2009 Dodge Neon 45.25 {camera lidar radar} 1
2015 Ford Fusion 90.89 {lidar} 0

传感器:

#ifndef SENSOR_H
#define SENSOR_H
#define MAX_CHAR 256
class Sensor{
    char type [MAX_CHAR];
    float extracost;
    static int gps_cnt, camera_cnt, lidar_cnt, radar_cnt;
public:
    Sensor();
    Sensor(char[]);
    Sensor(Sensor & other); 
    char* getType();
    float getExtraCost();
    void setType(char[]);
    void setExtraCost(char[]);
    void sensorCnt(char[]);
    static int getGPSCnt();
    static int getCameraCnt();
    static int getLidarCnt();
    static int getRadarCnt();
    static void resetGPSCnt();
    static void resetCameraCnt();
    static void resetLidarCnt();
    static void resetRadarCnt();
};
bool operator==(Sensor & sensor1, Sensor & sensor2);
#endif

sensor.cpp:

#include "Sensor.h"
#include "myStrings.h"
int Sensor::gps_cnt = 0;
int Sensor::camera_cnt = 0;
int Sensor::lidar_cnt = 0;
int Sensor::radar_cnt = 0;
Sensor::Sensor(){
    type[0] = '';
    extracost = 0;
}
Sensor::Sensor(char sensorName[]){
    setType(sensorName);
}
Sensor::Sensor(Sensor & other){ 
    setType(other.type);
}
char* Sensor::getType(){
    return type;
}
float Sensor::getExtraCost(){
    return extracost;
}
void Sensor::setType(char typeSensor[]){
    myStrings::strCpy(type,typeSensor);
    sensorCnt(typeSensor);
    setExtraCost(typeSensor);
}
void Sensor::setExtraCost(char newType[]){
    if(myStrings::strCmp(newType,"gps") == 0){
        extracost = 5;
    }
    if(myStrings::strCmp(newType, "camera") == 0){
        extracost = 10;
    }
    if(myStrings::strCmp(newType, "lidar") == 0){
        extracost = 15;
    }
    if(myStrings::strCmp(newType, "radar") == 0){
        extracost = 20;
    }
    if(myStrings::strCmp(newType, "") == 0){
        extracost = 0;
    }
}
void Sensor::sensorCnt(char sensorType[]){
    if(myStrings::strCmp(sensorType,"gps") == 0){
        gps_cnt++;
    }
    if(myStrings::strCmp(sensorType, "camera") == 0){
        camera_cnt++;
    }
    if(myStrings::strCmp(sensorType, "lidar") == 0){
        lidar_cnt++;
    }
    if(myStrings::strCmp(sensorType, "radar") == 0){
        radar_cnt++;
    }
}
int Sensor::getGPSCnt(){
return gps_cnt;
}
int Sensor::getCameraCnt(){
    return camera_cnt;
}
int Sensor::getLidarCnt(){
    return lidar_cnt;
}
int Sensor::getRadarCnt(){
    return radar_cnt;
}
void Sensor::resetGPSCnt(){
    gps_cnt = 0;
}
void Sensor::resetCameraCnt(){
    camera_cnt = 0;
}
void Sensor::resetLidarCnt(){
    lidar_cnt = 0;
}
void Sensor::resetRadarCnt(){
    radar_cnt = 0;
}
bool operator==(Sensor& sensor1, Sensor& sensor2){
    return (myStrings::strCmp(sensor1.getType(),sensor2.getType()) == 0);
}

car.h:

#ifndef CAR_H
#define CAR_H
#define MAX_SENS 3
#include "Sensor.h"
class Car{
    char make[MAX_CHAR];
    char model[MAX_CHAR];
    int year;
    Sensor sensor[MAX_SENS];
    float baseprice, finalprice;
    bool available;
public:
    Car();
    Car(char[], char[], int, float, Sensor[], bool);
    Car(Car & other);
    char* getMake();
    char* getModel();
    int getYear();
    float getBasePrice();
    float getFinalPrice(); 
    bool getAvailable();
    void setMake(char[]);
    void setModel(char[]);
    void setYear(int);
    void setBasePrice(float);
    void setAvailable(bool);
    void updatePrice();
    void print();
    float estimateCost(int);
    void addSensor(Sensor[]);
};
#endif

car.cpp:

#include <iostream>
#include "Car.h"
#include "myStrings.h"
Car::Car(){
    make[0] = '';
    model[0] = '';
    year = 0;
    baseprice = 0;
    finalprice = 0;
    available = false;
}
Car::Car(char newMake[], char newModel[], int newYear, float newBasePrice, Sensor newSensor[], bool newAvailable){
    setMake(newMake);
    setModel(newModel);
    setYear(newYear);
    setBasePrice(newBasePrice);
    setAvailable(newAvailable);
    addSensor(newSensor);
}
Car::Car(Car & other){
    setMake(other.make);
    setModel(other.model);
    setYear(other.year);
    setBasePrice(other.baseprice);
    setAvailable(other.available);
    addSensor(other.sensor);
}
char* Car::getMake(){
    return make;
}
char* Car::getModel(){
    return model;
}
int Car::getYear(){
    return year;
}
float Car::getBasePrice(){
    return baseprice;
}
float Car::getFinalPrice(){
    return finalprice;
}
bool Car::getAvailable(){
    return available;
}
void Car::setMake(char m_make[]){
    myStrings::strCpy(make,m_make);
}
void Car::setModel(char m_model[]){
    myStrings::strCpy(model,m_model);
}
void Car::setYear(int m_year){
    year = m_year;
}
void Car::setBasePrice(float m_baseprice){
    baseprice = m_baseprice;
}
void Car::setAvailable(bool m_available){
    available = m_available;
}
void Car::updatePrice(){
    for (int i = 0; i < MAX_SENS; i++){
        finalprice += sensor[i].getExtraCost();
    }
    finalprice += baseprice;
}
void Car::print(){
    updatePrice();
    std::cout << year << " " << make << " " << model << ", $" << baseprice << " per day,";
    for (int i = 0; i < MAX_SENS; i++){
        std::cout << " " << sensor[i].getType() << " ";
    }
    std::cout << " Available: " << std::boolalpha << available;
    std::cout << std::endl;
}
float Car::estimateCost(int days){
    return (finalprice * days); 
}
void Car::addSensor(Sensor sensorAdd[]){
    for (int i = 0; i < MAX_SENS; i++){
        char temp[MAX_CHAR];
        myStrings::strCpy(temp,sensorAdd[i].getType());
        sensor[i].setType(temp);
    }
}

代理:

#ifndef AGENCY_H
#define AGENCY_H
#define MAX_CARS 5
#include "Car.h"
class Agency{
    char name[MAX_CHAR];
    int zipcode;
    Car inventory[MAX_CARS];
public:
    Agency();
    char* getName();
    int getZipcode();
    void setName(char[]);
    void setZipcode(int);
    void readAllData(Car []);
    void printAllData(Car []);
    void printAvailableCars(Car []); 
};
#endif

agence.cpp:

#include <iostream>
#include <fstream>
#include "Agency.h"
#include "myStrings.h"
#define MAX_LEN 25
Agency::Agency(){
    name[0] = '';
    zipcode = 0;
}
char* Agency::getName(){
    return name;
}
int Agency::getZipcode(){
    return zipcode;
}
void Agency::setName(char newName[]){
    myStrings::strCpy(name, newName);
}
void Agency::setZipcode(int newZipcode){
    zipcode = newZipcode;
}
void Agency::readAllData(Car data[]){
    char inputFile[MAX_LEN];
    int tempYear;
    char tempMake[MAX_CHAR];
    char tempModel[MAX_CHAR];
    float tempPrice;
    char tempSensor[MAX_CHAR];
    Sensor sens[MAX_SENS];
    bool tempAvailable;
    std::ifstream inputStream;
    std::cout << "Enter input file name: ";
    std::cin >> inputFile;
    inputStream.open(inputFile);
    if(inputStream.is_open()){
        std::cout << std::endl;
        std::cout << "*" << inputFile << " has been read.*" << std::endl;
        std::cout << std::endl;
        inputStream >> name >> zipcode;
        for(int i = 0; i < MAX_CARS; i++){
            inputStream >> tempYear >> tempMake >> tempModel >> tempPrice >> tempSensor >> tempAvailable;
            inventory[i].setYear(tempYear);
            inventory[i].setMake(tempMake);
            inventory[i].setModel(tempModel);
            inventory[i].setBasePrice(tempPrice);
            for (int j = 0; j < MAX_SENS; j++){
                sens[j].setType(tempSensor);
                myStrings::strCpy(tempSensor,sens[j].getType());
                inventory[i].addSensor(sens);
            }
        inventory[i].setAvailable(tempAvailable);
        }
    }
if(!inputStream.is_open()){
        std::cerr << "Failed to open file: " << inputFile << std::endl;
    }
}
void Agency::printAllData(Car data[]){
    std::cout << name << " " << zipcode;
    std::cout << std::endl;
    for(int i = 0; i < MAX_CARS; i++){
        inventory[i].print();
    }
    std::cout << std::endl;
}
void Agency::printAvailableCars(Car data[]){
    std::cout << name << " " << zipcode;
    for(int i = 0; i < MAX_CARS; i++){
        if(inventory[i].getAvailable() == 1){
        std::cout << inventory[i].getYear() << " " << inventory[i].getMake() << " " << inventory[i].getModel() << ", " << "$" << inventory[i].getFinalPrice() << " per day" << std::endl;
        }
    }
    std::cout << std:: endl;    
}

proj4.cpp(驱动程序(:(目前测试阅读输入(

#include <iostream>
#include <fstream>
#include "Agency.h"
int main()
{
    Agency data;
    Car cars[9];
    data.readAllData(cars);
    data.printAllData(cars);
    return 0;
}

这就是印刷到终端的内容。

Enterprise 89502
2014 Toyota Tacoma, $115.12 per day, {gps}  {gps}  {gps}  Available: true
2012 Honda CRV, $85.1 per day, {camera  {camera  {camera  Available: false
2012 Honda CRV, $85.1 per day, {camera  {camera  {camera  Available: false
2012 Honda CRV, $85.1 per day, {camera  {camera  {camera  Available: false
2012 Honda CRV, $85.1 per day, {camera  {camera  {camera  Available: false

,但我想要:

Enterprise 89502
2014 Toyota Tacoma, $115.12 per day, {gps}  Available: true
2012 Honda CRV, $85.1 per day, {camera  lidar}  Available: false
2011 Toyota Rav4, $65.02 per day, {}  Available: false
2009 Dodge Neon, $45.25 per day, {camera  lidar  radar}  Available: true
2015 Ford Fusion, $90.89 per day, {lidar}  Available: true

我知道我正在阅读我的输入存在问题。在agenth.cpp中的函数readalldata中。

void Agency::readAllData(Car data[]){
    char inputFile[MAX_LEN];
    int tempYear;
    char tempMake[MAX_CHAR];
    char tempModel[MAX_CHAR];
    float tempPrice;
    char tempSensor[MAX_CHAR];
    Sensor sens[MAX_SENS];
    bool tempAvailable;
    std::ifstream inputStream;
    std::cout << "Enter input file name: ";
    std::cin >> inputFile;
    inputStream.open(inputFile);
    if(inputStream.is_open()){
        std::cout << std::endl;
        std::cout << "*" << inputFile << " has been read.*" << std::endl;
        std::cout << std::endl;
        inputStream >> name >> zipcode;
        for(int i = 0; i < MAX_CARS; i++){
            inputStream >> tempYear >> tempMake >> tempModel >> tempPrice >> tempSensor >> tempAvailable;
            inventory[i].setYear(tempYear);
            inventory[i].setMake(tempMake);
            inventory[i].setModel(tempModel);
            inventory[i].setBasePrice(tempPrice);
            for (int j = 0; j < MAX_SENS; j++){
                sens[j].setType(tempSensor);
                myStrings::strCpy(tempSensor,sens[j].getType());
                inventory[i].addSensor(sens);
            }
        inventory[i].setAvailable(tempAvailable);
        }
    }
if(!inputStream.is_open()){
        std::cerr << "Failed to open file: " << inputFile << std::endl;
    }
}

我认为正在发生的事情是,它在读取价格后,它将寻找下一组字符,并将一个"单词"存储到tempsensor中。

对于第一行:

2014 Toyota Tacoma 115.12 {gps} 1

它将{gps}作为tempsensor存储,并将其存储3次。

因此:

2014 Toyota Tacoma, $115.12 per day, {gps}  {gps}  {gps}  Available: true

第二行:

2012 Honda CRV 85.10 {camera lidar} 0 

它存储{相机作为tempsensor。并存储{相机三次。一旦它击中了空格,它就会移至tempavailable,但它在LIDAR中读取,并且由于期望它会输入Bool输入,因此它会使程序弄乱,这就是为什么它不断为Honda打印数据的原因。

因此:

2012 Honda CRV, $85.1 per day, {camera  {camera  {camera  Available: false
2012 Honda CRV, $85.1 per day, {camera  {camera  {camera  Available: false
2012 Honda CRV, $85.1 per day, {camera  {camera  {camera  Available: false
2012 Honda CRV, $85.1 per day, {camera  {camera  {camera  Available: false

我知道我需要实现某些东西,以便它知道使用tempsensor寻找3个单词,并排除" {''and'}"。

我坚持如何做。

您可以使用 std::istringstream,而不必使用现在所有逻辑来解析字符串。您甚至可以保留所有角色阵列,而无需使用std::string

#include <sstream>
#include <iostream>
int main()
{
    char s[] = "2014 Toyota Tacoma 115.12 {gps} 1";
    int year;
    char make1[100], make2[100];
    double price;
    char category[100];
    int num;
    std::istringstream iss(s);
    iss >> year >> make1 >> make2 >> price >> category >> num;
    std::cout << year << "n";
    std::cout << make1 << "n";
    std::cout << make2 << "n";
    std::cout << price << "n";
    std::cout << category  << "n";
    std::cout << num;    
}    

输出:

2014
Toyota
Tacoma
115.12
{gps}
1

如果卷曲支架数据具有多个元素,则可以完全实现解析数据。它基本上将指针设置在字符串中,然后将字符串的那一部分馈送到std::istringstream以使其具有解析的魔力:

#include <sstream>
#include <iostream>
#include <cstring>
int main()
{
    char s[] = "2014 Toyota Tacoma 115.12 {gps gps2 gps3} 1";
    // get the position of the braces and save this to a string
    char *pos1 = strchr(s,'{') + 1; // opening brace pointer
    char *pos2 = strchr(s,'}');     // closing brace pointer
    char curly_string[100] = {};
    strncpy(curly_string, pos1, pos2-pos1); // copy everything between these pointers
    // The last value is always located after the closing brace
    char *numpos = pos2 + 1;
    // parse the individual entries
    int year;
    char make1[100], make2[100];
    double price;
    int num;
    // Output the stuff before the curly brace
    std::istringstream iss(s);
    iss >> year >> make1 >> make2 >> price; 
    std::cout << year << "n";
    std::cout << make1 << "n";
    std::cout << make2 << "n";
    std::cout << price << "n";
    // Output the curly string stuff and its contents
    iss.clear();
    iss.str(curly_string);
    char one_category[100];
    while (iss >> one_category)
        std::cout << one_category << "n";
    // output the last item (the number)
    iss.clear();
    iss.str(numpos);
    iss >> num;
    std::cout << num;
}    

输出:

2014
Toyota
Tacoma
115.12
gps
gps2
gps3
1

请注意,std::string作为类型而不是char数组来容易得多。使用char阵列很浪费,因为我必须声明具有100个条目的阵列。

如果您必须使用字符数组,则使用istream::getline与分界符:

static const unsigned int MAX_LENGTH_MAKE_MODEL = 256;
char make_and_model[MAX_LENGTH_MAKE_MODEL];
inputStream.getline(make_and_model, MAX_LENGTH_MAKE_MODEL, ','];

,或者您可以在整行中阅读,然后搜索并提取子字符串:

static const unsigned int MAX_LINE_LENGTH = 4096;
char line_of_text[MAX_LINE_LENGTH];
inputStream.getline(line_of_text, MAX_LINE_LENGTH, 'n');
char * p_comma = strchr(line_of_text, ',');
//...

还研究strtok功能。