samedi 13 mars 2021

I don't know what to make of "terminate called after throwing an instance of std out of range what (): basic_string:at_n (which is 0)"

I am working on a program for a homework assignment. It is a bit of a game where balloons of different colors are collected. The user is asked to give their name and favorite color and if the color is valid, the program will loop, reading through a file named game.dat. game.dat contains lines like this "YelloW:3:The functional hotel". After reading a line the balloon and it's points (the 3 in this case) are either given to the user if the color is the user's favorite, or nothing is done with it.

I keep getting this problem when I run the program however, after entering a valid color I get "terminate called after throwing an instance of std out of range what (): basic_string:at_n (which is 0) >= this->size() (which is 0) Aborted (core dumped)". I don't see anything wrong with my code and I feel I followed the assignment's directions correctly but something must be off.

I am not allowed to change the names, types, or parameters of any functions and I can only edit ReadPlayer, PrintPlayer, ReadBalloon, PrintBalloons, and GiveBalloon. The other functions were given by the professor.

I am new to C++ and will greatly appreciate any help you can give me, thank you.

#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <fstream>

using namespace std;

enum class ColorT {RED, YELLOW,  GREEN, CYAN,  BLUE, MAGENTA, NO_COLOR};

const ColorT FIRST_COLOR = ColorT::RED;

const size_t COLOR_COUNT = static_cast<int>(ColorT::NO_COLOR);

struct PlayerT {
    string name;
    int score;
    ColorT favColor;
};

struct BalloonT {
    ColorT balloonColor;
    int balloonValue;
    string balloonLocation;
};

void ReadPlayer(PlayerT & player);
void PrintPlayer(PlayerT player);
BalloonT ReadBalloon(ifstream & stream);
void PrintBalloon(BalloonT balloon);
void GiveBalloon(PlayerT & player, BalloonT balloon);

ColorT NextColorT(ColorT color);
string ColorTToString(ColorT color);
ColorT StringToColorT(string word);

string ToUpperString(string word);
ColorT RandomColor(void);

int main() {
    PlayerT player;
    BalloonT balloon;
    ifstream stream;
    string fileName = "game.dat";
    
    ReadPlayer(player);
    stream.open(fileName);
    ReadBalloon(stream);
    while (balloon.balloonColor == ColorT::RED || balloon.balloonColor == ColorT::YELLOW || 
            balloon.balloonColor == ColorT::GREEN || balloon.balloonColor == ColorT::CYAN || 
            balloon.balloonColor == ColorT::BLUE || 
            balloon.balloonColor == ColorT::MAGENTA) {
        PrintBalloon(balloon);
        GiveBalloon(player, balloon);
        PrintPlayer(player);
        cout << endl;
    }
    stream.close();
    
    cout << player.name << " your final score is " << player.score << "." << endl;

    return 0;
}

ColorT NextColorT(ColorT color) {
    ColorT result = ColorT::NO_COLOR;

    if(color < ColorT::NO_COLOR) {
         result = static_cast<ColorT>(static_cast<int>(color) + 1);
    }

    return result;
}

string ColorTToString(ColorT color) {
    string result;

    switch(color) {
        case ColorT::RED:
            result = "red";
            break;
        case ColorT::GREEN:
            result = "green";
            break;
        case ColorT::BLUE:
            result = "blue";
            break;
        case ColorT::CYAN:
            result = "cyan";
            break;
        case ColorT::MAGENTA:
            result = "magenta";
            break;
        case ColorT::YELLOW:
            result = "yellow";
            break;
        case ColorT::NO_COLOR:
            [[fallthrough]];
        default:
            result = "Color Not Defined";
    }

    return result;
}

ColorT StringToColorT(string word) {
    ColorT result = ColorT::NO_COLOR;

    word = ToUpperString(word);
    
    if (word == "RED"){
        result = ColorT::RED;
    } else if (word == "GREEN") {
        result = ColorT::GREEN;
    } else if (word == "BLUE") {
        result = ColorT::BLUE;
    } else if (word == "CYAN") {
        result = ColorT::CYAN;
    } else if (word == "MAGENTA") {
        result = ColorT::MAGENTA;
    } else if (word == "YELLOW") {
        result = ColorT::YELLOW;
    }

    return result;
}

string ToUpperString(string word){
    size_t i;

    for(i = 0; i < word.size(); i++) {
        word[i] = static_cast<char>(toupper(word[i]));
    }

    return word;
}

ColorT RandomColor(){
     ColorT result;

     result = static_cast<ColorT>(rand() % COLOR_COUNT );
     return result;

}

void ReadPlayer(PlayerT & player) {
    
    string color;
    
    cout << "Enter the player's name: ";
    cin >> player.name;
    cout << endl;
    
    player.score = 0;
    
    ColorT USER_COLOR = ColorT::NO_COLOR;
    
    while (USER_COLOR == ColorT::NO_COLOR) {
        cout << "Enter the player's favorite color: ";
        cin >> color;
        cout << endl;
        USER_COLOR = StringToColorT(color);
        if (USER_COLOR != ColorT::RED && USER_COLOR != ColorT::YELLOW && 
            USER_COLOR != ColorT::GREEN && USER_COLOR != ColorT::CYAN && 
            USER_COLOR != ColorT::BLUE && USER_COLOR != ColorT::MAGENTA) {
                cout << "Sorry " << color << " is not a valid color." << endl;
                cout << "Please select again" << endl;
        }
    player.favColor = USER_COLOR;
    
    }
}

void PrintPlayer(PlayerT player) {

    string color;

    color = ColorTToString(player.favColor);

    cout << "Balloon Hunter: " << player.name << endl;
    cout << "Favorite Color: " << color << endl;
    cout << "Score: " << player.score << endl;
    
}

BalloonT ReadBalloon (ifstream & stream) {
    BalloonT result;
    
    string color;
    char junk = 0;
    
    stream >> color;
    result.balloonColor = StringToColorT(color);
    stream >> result.balloonValue;
    stream >> junk;
    getline(stream, result.balloonLocation);
    
    if (result.balloonColor != ColorT::RED && result.balloonColor != ColorT::YELLOW && 
            result.balloonColor != ColorT::GREEN && result.balloonColor != ColorT::CYAN && 
            result.balloonColor != ColorT::BLUE && 
            result.balloonColor != ColorT::MAGENTA) {
                //result.balloonColor = ColorT::NO_COLOR;
            }
    
    return result;
    
}

void PrintBalloon(BalloonT balloon) {
    
    string color;
    color = ColorTToString(balloon.balloonColor);
    
    tolower(balloon.balloonLocation.at(0));
    
    cout << "You found a " << color << " balloon in " << balloon.balloonLocation <<
    " worth " << balloon.balloonValue << " points." << endl;
    
}

void GiveBalloon(PlayerT & player, BalloonT balloon) {
    
    if (balloon.balloonColor == player.favColor) {
        
        cout << "Thank you, I love " << ColorTToString(balloon.balloonColor) <<
        " balloons!" << endl;
        
        player.score = player.score + balloon.balloonValue; 
    }
    else {
        
        cout << "No thank you, I don't like " << ColorTToString(balloon.balloonColor) <<
        " balloons." << endl;
        
    }
    
}

Aucun commentaire:

Enregistrer un commentaire