My valid data(Records.txt) keeps outputting onto the wrong case statment.
Records.txt:
AB12MP349 Fusion5 20 17000.00
33435KMOP324 BMW 40 25000.00
AB12MP349 Audi 100 4000.00
AB12MP349 Pagni 1 2000000.00
As you can see below, when the user presses 1 it gives them 1/3 of valid records, but than displays the last two valid records onto InvalidRecords.
Output:
./test
Welcome to Car Database Lookup
----------------------------------------
Press 1 to display a table of valid car records:
Press 2 to display a table full of InvalidRecords:
Type here: 1
Car ID Model Quantity Price
AB12MP349 Fusion5 20 17000
Press 2 to display a table full of InvalidRecords:
Type here: 2
Invalid car IDs:
33435KMOP324
BMW
40
25000.00
AB12MP349
Audi
100
4000.00
AB12MP349
Pagni
1
2000000.00
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <vector>
#include <cctype>
using namespace std;
// Class to store information about cars
class CarData {
public:
string CarID;
string Model;
int Quantity;
double Price;
// Constructor to initialize CarData class(Parameters)
CarData(const string &carID, const string &model, int quantity, double price)
: CarID(carID), Model(model), Quantity(quantity), Price(price) {}
};
// Function prototypes
bool dataValidation(char d);
bool IsValidCarID(const string &carID);
bool DataCarPrice(double price);
void TakeCarData(vector<CarData> &carInfo, vector<string> &invalidCarIDs);
int main() {
// Menu for User
enum uiforUser {
DISPLAY_CARINFO = 1,
DISPLAY_ERROR = 2,
};
int userInput;
cout << "\nWelcome to Pierce Car Database Lookup\n";
cout << setfill('-');
cout << setw(40) << "-" << endl;
cout << "Press " << DISPLAY_CARINFO << " to display a table of valid car records: ";
cout << endl;
cout << "Press " << DISPLAY_ERROR << " to display a table full of Invalid Records: ";
cout << "\nType here: ";
cin >> userInput;
// Used a Vector because it can hold many values and etc(Sequence Container !)
vector<string> invalidCarIDs;
vector<CarData> carInfo;
switch (userInput) {
// Menu To display Valid Records
case DISPLAY_CARINFO: {
TakeCarData(carInfo, invalidCarIDs); // Getting Parameters from Function(TakeCarData)
// Output for valid Records
cout << setfill(' ');
cout << setw(27) << "Car ID";
cout << setw(20) << "Model";
cout << setw(19) << "Quantity";
cout << setw(16) << "Price";
cout << endl << endl;
// for loop that uses a pointer(Record), this allows me to access the data from carInfo!
for (const CarData &Record : carInfo) {
cout << setw(29) << Record.CarID;
cout << setw(19) << Record.Model;
cout << setw(18) << Record.Quantity;
cout << setw(16) << Record.Price;
cout << endl;
}
}
break;
// Menu to display Record Errors
case DISPLAY_ERROR: {
TakeCarData(carInfo, invalidCarIDs); // Grabbing Parameters from Function below
cout << "Invalid car IDs:" << endl;
// for loop that uses a pointer(invalidID), this is allows me to access to data Validation Function
for (const string &invalidID : invalidCarIDs) {
cout << invalidID << endl;
}
}
break;
}
return 0;
}
// DataValidation Logic !
bool dataValidation(char d) {
// Checks if a character's range from A-Z, also checks for "O"
return (d >= 'A' && d <= 'Z' && d != 'O');
}
bool DataCarPrice(double &price) {
if (price <= 5000) {
cout << "test";
}
return false;
}
bool IsValidCarID(const string &carID) {
// checks length of CarID(9 characters long)
if (carID.length() != 9) {
return false;
}
if (!dataValidation(carID[0]) || !dataValidation(carID[1])) {
return false;
}
for (int i = 2; i < 6; ++i) {
// isalnum is used because it can check if a value is alphanumeric
if (!isalnum(carID[i]) || carID[i] == 'O') {
return false;
}
}
for (int i = 3; i < 6; ++i) {
if (!isdigit(carID[i])) {
return false;
}
}
return true;
}
void TakeCarData(vector<CarData> &carInfo, vector<string> &invalidCarIDs) {
ifstream RecordFile;
RecordFile.open("Records.txt");
if (!RecordFile) {
cout << "File not found. Please check the file path." << endl;
system("pause");
exit(EXIT_FAILURE);
}
// Read data from the file and add it to the vector
string carID, model;
int quantity;
double price;
while (RecordFile >> carID >> model >> quantity >> price) {
carInfo.emplace_back(carID, model, quantity, price); // Add car data to the vector
}
while (RecordFile >> carID) {
invalidCarIDs.emplace_back(carID);
}
RecordFile.close();
// Open an output file (if needed)
ofstream DataBase;
DataBase.open("Output.txt");
if (!DataBase) {
cout << "Output file not found. Please check the file path." << endl;
system("pause");
exit(EXIT_FAILURE);
}
// Close files when done
DataBase.close();
}
I modified the TakeCarData function to separate valid car data from invalid car IDs and populate the corresponding vectors based on the user's choice.