mardi 9 février 2021

std::length_error using std::string. g++ on Ubuntu 20.04

Hello I am new to programming in C++ in Linux. I originally wrote this code in VS Community 2019 in Windows and wanted to learn Linux. However I am having an issue with std::string that I have never seen in the Windows version. I prompt the user for some data for adding a new account, and I use getline() with strings. the first one works great, however the second one throws an error:

terminate called after throwing an instance of 'std::length_error'
what():  basic_string::_M_create
Aborted (core dumped)

Here is the code:

addAcc()

/*****************************************************
* Add new Account:
* Prompts the user for several inputs to add details *
* about about the new Account being added to the DB  *
*****************************************************/
void Account::addAcc(){
    bool complete = false;
    bool valid = false;
    std::vector<int> dateVec;
    char charSel = ' ';

    // Instantiate class instance
    Date* date = new Date();
    
    while (!complete){
        std::cin.ignore();
        
        // Get Financial Institution Name
        m_instName = setInstName();
        std::cout << std::endl << std::endl;

        // Get Account Name
        m_accName = setAccName();
        std::cout << std::endl << std::endl;

        // Set Account Type
        m_accType = setAccType();
        std::cout << std::endl << std::endl;

        // Does Account accrue Interest
        m_interest = setAccInterest();
        std::cout << std::endl << std::endl;

        // Is Account Active
        m_active = setAccStatus();
        std::cout << std::endl << std::endl;

        // Set Balance for Account
        m_balance = setAccBal();
        std::cout << std::endl << std::endl;

        // Set Projected Balance to 0.0
        m_proj_bal = 0.0;

        // Set Open Date for Account
        dateVec.clear();
        dateVec.erase(dateVec.begin(), dateVec.end());
        setOpenDate(dateVec);

        // Convert from int to string
        m_openDate = date->dateToString(dateVec);

        // Get a human readable date
        m_rDate = date->rDateString(m_openDate);

        // Print out user input for visual verification
        valid = false;
        while (!valid){
            // Get string representation for the Account type
            m_typeStr = getAccTypeName(m_accType);

            // For showing if Account accrues interest
            // If interest = 0, display No
            // else display Yes
            if (m_interest == 0) {
                m_interestStr = "No";
            }
            else {
                m_interestStr = "Yes";
            }

            // For is Account open/closed
            // If active = 0, display No
            // Else, display Yes
            if (m_active == 0) {
                m_activeStr = "No";
            }
            else {
                m_activeStr = "Yes";
            }

            // Display user input
            std::cout << m_rDate << " - " << m_instName << " - " << m_accName << " - " << m_typeStr << " - " << m_interestStr << " - " << m_activeStr << " - " << "$" << m_balance << std::endl;
            std::cin.clear();
            std::cin.ignore();
            std::cout << "Is this correct? [Y/N]: ";
            std::cin >> charSel;
            std::cout << std::endl << std::endl;
    
            // Verify char input
            if (charSel == 'y' || charSel == 'Y' || charSel == 'n' || charSel == 'N') {
                valid = true;
            }
            else {
                std::cout << charSel << " is not a valid selection! Please try again!" << std::endl;
                std::cin.clear();
                std::cin.ignore();
                std::cout << "Press [Enter] to continue..." << std::endl << std::endl;
                continue;
            }
        }
        if (charSel == 'n' || charSel == 'N') {
            continue;
        }
        else if (charSel == 'y' || charSel == 'Y') {
            // Add user input to DB
            Account* Acct = new Account(m_instName, m_accType, m_accName, m_active, m_balance, m_interest, m_openDate, dateVec[2], dateVec[1], dateVec[0]);
            (void)Acct;

            // Ask User if another Account is needed
            valid = false;
            while (!valid) {
                charSel = ' ';
                std::cout << "Another?: [Y/N]";
                std::cin >> charSel;
                std::cout << std::endl << std::endl;
                if (charSel == 'y' || charSel == 'Y' || charSel == 'n' || charSel == 'N') {
                    valid = true;
                }
                else {
                    std::cout << charSel << " is not a valid selection! Please try again!" << std::endl;
                    std::cin.clear();
                    std::cin.ignore();
                    continue;
                }
            }
            if (charSel == 'y' || charSel == 'Y') {
                continue;
            }
            else if (charSel == 'n' || charSel == 'N') {
                complete = true;
            }
        }
    }
}

setInstName() - Works Fine

/*********************************************
    * Get Institution name to add to new Account *
*********************************************/
std::string Account::setInstName(){
    std::cout << "Enter an Institution Name: ";
    std::getline(std::cin, m_instName);

    return m_instName;
}

setAccName() - Throws the error

/**********************************************
* Get Account nick name to add to new Account *
**********************************************/
std::string Account::setAccName() {
    std::cout << "Enter Account Name: ";
    std::getline(std::cin, m_accName);

    return m_accName;
}

My test input is very short: first input is only 4 characters while the second is 6 characters. Not sure why std::string is giving me such a hard time with this as I dont think I'm really doing anythin too extreme with it.

Aucun commentaire:

Enregistrer un commentaire