I am having trouble implementing a search function for each option case with my code. I am not sure how to actually search the files for the information that I need the code to output. I will attach the code I have so far.
Cars.h file
class Cars {
protected:
string make, model;
double price;
int miles;
public:
Cars(string make, string model, double price, int miles);
string getMake();
string getModel();
double getPrice();
int getMiles();
virtual void displayInfo();
};
Cars.cpp file
Cars::Cars(string make, string model, double price, int miles) {
this -> make = make;
this -> model = model;
this -> price = price;
this -> miles = miles;
}
string Cars::getMake() {
return make;
}
string Cars::getModel() {
return model;
}
double Cars::getPrice() {
return price;
}
int Cars::getMiles() {
return miles;
}
void Cars::displayInfo() {
cout << "Make: " << make << endl;
cout << "Model: " << model << endl;
cout << "Price: $" << price << endl;
cout << "Miles: " << miles << endl;
}
Sedans.h file
class Sedans : public Cars {
private:
bool hybrid;
public:
Sedans(string make, string model, double price, int miles, bool hybrid);
void displayInfo() override;
};
Sedans.cpp file
Sedans::Sedans(string make, string model, double price, int miles, bool hybrid) : Cars(make, model, price, miles) {
this -> make = make;
this -> model = model;
this -> price = price;
this -> miles = miles;
this -> hybrid = hybrid;
}
void Sedans::displayInfo() {
Cars::displayInfo();
cout << "Hybrid: " << (hybrid ? "yes" : "no") << endl;
}
Trucks.h file
class Trucks : public Cars {
private:
string engine;
public:
Trucks(string make, string model, double price, int miles, string engine);
void displayInfo() override;
};
Trucks.cpp file
Trucks::Trucks(string make, string model, double price, int miles, string engine) : Cars(make, model, price, miles) {
this -> make = make;
this -> model = model;
this -> price = price;
this -> miles = miles;
this -> engine = engine;
}
void Trucks::displayInfo() {
Cars::displayInfo();
cout << "Engine: " << engine << endl;
}
main.cpp file
using namespace std;
int main() {
ifstream sedansFile;
sedansFile.open("sedans-1.txt");
ifstream trucksFile;
trucksFile.open("trucks-1.txt");
int option;
string searchText;
bool exit = false;
cout << "**********SEARCH MENU***********" << endl;
cout << "Search Make..............Press 1" << endl;
cout << "Search Model.............Press 2" << endl;
cout << "Search Price.............Press 3" << endl;
cout << "Search Miles.............Press 4" << endl;
cout << "Exit.....................Press 5" << endl;
while (!exit) {
cout << "\nSelect Option: ";
cin >> option;
if (option == 5) {
exit = true;
continue;
}
cout << "Enter Search Text: ";
cin.ignore();
getline(cin, searchText);
cout << endl;
}
return 0;
}
Basically I need this output:
Select Option: 1
Enter Search Text: Toyota
Make: Toyota
Model: Tundra
Miles: 68058
Price: $35348.00
Engine: V6
Make: Toyota
Model: Camry
Miles: 20597
Price: $35348.00
Hybrid: yes
Each option will give different search criteria and give me the cars that match.
The text files are as follows:
Sedans-1.txt
Toyota Camry 35348 20597 yes
Lexus ES 55609 4693 yes
Honda Accord 22987 11768 no
Trucks-1.txt
Toyota Tundra 34271 68058 V6
Ford F-150 55609 9785 V8
Nissan Titan 33990 2677 V6
I can't use vector or pushback in this problem. Ideally I want the most basic way to solve this without getting too involved. Solve as if a beginner is coding this.
Hmm... no
vector. Okay. So the plan is to open the files, and make a sequential scan of all the records each time a search is requested.This answer focuses on the search routines. At the end, demonstration code for one of them, function
display_trucks_for_given_make, is given. Along the way, several other functions are developed.Utility functions – Functions such as
to_int,to_double, andtrim_whitespace_vieware taken from my toolbox.Stream extraction operator –
operator>>, for classTrucks, reads a single record from the file.Convert strings into numbers
When
priceandmilesare read from a file, they will first be stored as strings. Those strings will be converted, respectively, into adoubleandintusing the functions below.Note: a commenter correctly pointed out that dollar amounts are best converted to pennies, and stored as
intvalues. Otherwise, round-off errors can be problematic. This answer, however, works with typedouble. Conversion to pennies is left up to the OP.For my own work, I use a template function that converts any numeric type. The template function returns a
std::optional, which is empty when the conversion fails.For this answer, which is geared towards beginners, I will ditch the template, and return a
bool, to indicate success or failure. The number itself is returned in a reference parameter.Prior to conversion,
trim_whitespace_viewis called to strip off any leading or trailing spaces.The conversion is carried out using std::from_chars, and must consume the entire input string. If there are any stray characters leftover, conversion fails.
Stream extraction functions
The data files both are structured with only one "word" per field. None of the fields include spaces.
In the future, perhaps they could be changed to CSV files (i.e., "comma-separated values"), which would allow a field to contains spaces. With CSV files, the delimiter character, which is used to separate fields, is (usually) a comma.
The files
sedans-1.txtandtrucks-1.txtcan both be treated as CSV files where the delimiter is the space character. Later on, by simply changing the delimiter to a comma, the functions below would work with true CSV files.The example below shows how to code a stream extraction operator for the Trucks file. It is implemented as a hidden friend. That is why it is coded within class
Trucks.If extraction fails for any of the fields, or one of the numeric fields fails to convert,
operator>>throws astd::runtime_error.I have taken the liberty of adding a default constructor to class
Trucks. That allows you to construct an emptyTrucksobject, prior to invoking the stream extraction operator.Note, as well, that I have included header
tbx.utility.h, from the preceding section.The four search functions declared at the end of Trucks header are discussed in the next section.
The operator for the Sedans file is similar.
A typical search function
Here is an example of one of the search functions. This one searches the Trucks file for a given
make, and displays data for any truck that matches. Note that the search functions are all free functions, declared outside of any class.Two functions from the utility toolbox,
tbx::to_lowerandtbx::to_lower_in_place, convert their string arguments to lower case. Before comparing a vehicle make against the searchText, both are converted to lower case.The file is opened anew every time a search function is called. Upon exit from a search function, the file is closed automatically (by its destructor).
The other search functions are similar.