C++ 如何将文件中的数据读入类的数组

C++ 如何将文件中的数据读入类的数组,c++,file-io,C++,File Io,这项作业包括制作一个程序,从文本文件中读取汽车代理商及其汽车+汽车信息 具体地说,我应该读入汽车代理商的名称、汽车代理商的邮政编码,然后读入汽车的年份、品牌、型号、传感器和可用性 我很难在传感器中读取数据,因为它在带有“{”和“}”的文本文件中的显示方式。最大传感器也是3个,但并非每辆车都有3个 我创建了传感器、汽车和代理类 输入文件HighTechAgency.txt: Enterprise 89502 2014 Toyota Tacoma 115.12 {gps} 1 2012 Honda

这项作业包括制作一个程序,从文本文件中读取汽车代理商及其汽车+汽车信息

具体地说,我应该读入汽车代理商的名称、汽车代理商的邮政编码,然后读入汽车的年份、品牌、型号、传感器和可用性

我很难在传感器中读取数据,因为它在带有“{”和“}”的文本文件中的显示方式。最大传感器也是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
传感器h:

#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] = '\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] = '\0';
    model[0] = '\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);
    }
}
Agency.cpp:

#include <iostream>
#include <fstream>
#include "Agency.h"
#include "myStrings.h"
#define MAX_LEN 25

Agency::Agency(){
    name[0] = '\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;    
}
但我想要的是:

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
我知道在读取输入时存在问题。特别是在Agency.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;
    }
}
它将{gps}存储为tempSensor,并存储三次

因此:

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
第二行:

2012 Honda CRV 85.10 {camera lidar} 0 
它将{camera作为tempSensor存储。并将{camera存储三次。一旦它点击空白,然后移动到tempavable,但它在激光雷达中读取,因为它需要bool输入,所以它会弄乱程序,这就是为什么它一直为本田打印数据

因此:

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
我知道我需要实现一些东西,以便它知道使用tempSensor查找3个单词,并排除“{”和“}”


不过,我一直在想如何做到这一点。

如果必须使用字符数组,请与分隔符一起使用:

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函数。

您可以使用std::istringstream,而不必使用现在所有的逻辑来解析字符串。您甚至可以保留所有字符数组,而不需要使用std::string:

如果大括号数据有多个元素,下面是解析数据的完整实现。它基本上在字符串中设置指针,然后将字符串的该部分馈送到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;
}    

请注意,使用std::string作为类型而不是char数组更容易。使用char数组是浪费的,因为我必须声明包含100个条目的数组。

这是大量代码。请尝试制作一个简单的示例。基本问题是,当您的输入不包含单词时,您试图读取单词。尽管我不容易切换到读行,然后分析每一行来提取所需的信息。不要期望这是容易的,不要指望C++中的任何快速的修改来帮助你,你必须自己去分析你的输入。char数组可以溢出。记住使用字符数组的STR函数:strcmp、strdup和strchr.@whiteferrari如果你先读,我建议你读一整行,然后再分析和提取数据。实际上,这只是一个问题,你只需逐字阅读字符串,寻找你感兴趣的东西,描绘出你的数据逗号、空格和{}@whiteferrari-我已经为我的字符串函数创建了一个类-你应该创建一个字符串类,而不仅仅是一个函数类。然后你可以用这个类替换你现在所有的char[],但是如果我想在{camera lidar radar}中阅读呢另外,我需要把这些值存储到一个传感器数组中,你可以使用相同的技术。在一个字符串中存储,而不是起始和结束括号,在这个新的字符串上使用STD::ISTIGSTROW。C++完全不需要手动解析简单的空间分隔数据。更具体地说,只要你有一个字符串。用空格分隔的项目,使用stringstream和>>来解析。
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, ',');
//...
#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
#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