如何将文件中的数据读取到 class 的数组中
How to read data from a file into an array of a class
此作业涉及编写一个程序,该程序将从文本文件中读取汽车代理商及其汽车(+汽车信息)。
具体来说,我应该读入汽车代理商名称、汽车代理商邮政编码,然后是汽车年份、制造商、型号、传感器及其可用性。
由于传感器在带有“{”和“}”的文本文件中的显示方式,我很难读取传感器。最大传感器也是 3 个,但每辆车并不总是 3 个。
我创建了 Sensor、Car 和 Agency 类。
输入文件(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
Sensor.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] = '[=13=]';
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] = '[=15=]';
model[0] = '[=15=]';
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.h:
#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
Agency.cpp:
#include <iostream>
#include <fstream>
#include "Agency.h"
#include "myStrings.h"
#define MAX_LEN 25
Agency::Agency(){
name[0] = '[=17=]';
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, 5.12 per day, {gps} {gps} {gps} Available: true
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
但我想要的是:
Enterprise 89502
2014 Toyota Tacoma, 5.12 per day, {gps} Available: true
2012 Honda CRV, .1 per day, {camera lidar} Available: false
2011 Toyota Rav4, .02 per day, {} Available: false
2009 Dodge Neon, .25 per day, {camera lidar radar} Available: true
2015 Ford Fusion, .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;
}
}
我认为发生的事情是在读取价格后,它会查找下一组字符并将该字符 "word" 存储到 tempSensor 中。
第一行:
2014 Toyota Tacoma 115.12 {gps} 1
存储{gps}为tempSensor,存储3次
因此:
2014 Toyota Tacoma, 5.12 per day, {gps} {gps} {gps} Available: true
第二行:
2012 Honda CRV 85.10 {camera lidar} 0
它将{相机存储为tempSensor。并存储{相机三次。一旦遇到空白,它就会移动到 tempAvailable,但它会读取激光雷达,并且由于它需要一个 bool 输入,所以它会搞乱程序,这就是它继续为本田打印数据的原因。
因此:
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
我知道我需要实现一些东西,以便它知道使用 tempSensor 查找 3 个词,并排除“{”和“}”。
虽然我不知道该怎么做。
如果必须使用字符数组,则使用 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
函数。
您可以使用 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 个条目的数组。
此作业涉及编写一个程序,该程序将从文本文件中读取汽车代理商及其汽车(+汽车信息)。
具体来说,我应该读入汽车代理商名称、汽车代理商邮政编码,然后是汽车年份、制造商、型号、传感器及其可用性。
由于传感器在带有“{”和“}”的文本文件中的显示方式,我很难读取传感器。最大传感器也是 3 个,但每辆车并不总是 3 个。
我创建了 Sensor、Car 和 Agency 类。
输入文件(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
Sensor.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] = '[=13=]';
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] = '[=15=]';
model[0] = '[=15=]';
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.h:
#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
Agency.cpp:
#include <iostream>
#include <fstream>
#include "Agency.h"
#include "myStrings.h"
#define MAX_LEN 25
Agency::Agency(){
name[0] = '[=17=]';
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, 5.12 per day, {gps} {gps} {gps} Available: true
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
但我想要的是:
Enterprise 89502
2014 Toyota Tacoma, 5.12 per day, {gps} Available: true
2012 Honda CRV, .1 per day, {camera lidar} Available: false
2011 Toyota Rav4, .02 per day, {} Available: false
2009 Dodge Neon, .25 per day, {camera lidar radar} Available: true
2015 Ford Fusion, .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;
}
}
我认为发生的事情是在读取价格后,它会查找下一组字符并将该字符 "word" 存储到 tempSensor 中。
第一行:
2014 Toyota Tacoma 115.12 {gps} 1
存储{gps}为tempSensor,存储3次
因此:
2014 Toyota Tacoma, 5.12 per day, {gps} {gps} {gps} Available: true
第二行:
2012 Honda CRV 85.10 {camera lidar} 0
它将{相机存储为tempSensor。并存储{相机三次。一旦遇到空白,它就会移动到 tempAvailable,但它会读取激光雷达,并且由于它需要一个 bool 输入,所以它会搞乱程序,这就是它继续为本田打印数据的原因。
因此:
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
2012 Honda CRV, .1 per day, {camera {camera {camera Available: false
我知道我需要实现一些东西,以便它知道使用 tempSensor 查找 3 个词,并排除“{”和“}”。
虽然我不知道该怎么做。
如果必须使用字符数组,则使用 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
函数。
您可以使用 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 个条目的数组。