0

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.

Jonny Henly
  • 4,023
  • 4
  • 26
  • 43
Zximy
  • 1
  • 1
  • 1
    Welcome to SO! Where do you do validation? Also, use a debugger (or "cout" some vars in a lot of places) to see those "while" loops in action. – Ripi2 Sep 02 '23 at 20:03
  • 1
    None of the car IDs seem to be valid. Take for instance `AB12MP349`, it's 5th character (`carID[4]`) is `M` which is not a digit. – Jonny Henly Sep 02 '23 at 20:23
  • You'll be glad to hear you don't need anyone's help to figure this out, just a tool you already have: your debugger! This is exactly what a debugger is for. It [runs your program, one line at a time, and shows you what's happening](https://stackoverflow.com/questions/25385173/), this is something that's every C++ developer must know how to do. With your debugger's help you'll able to quickly find all problems in this and all future programs you write, without having to ask anyone for help. Have you tried using your debugger, already? If not, why not? What did your debugger show you? – Sam Varshavchik Sep 02 '23 at 23:49

0 Answers0