0

I am making a rogue-like ASCII game and made a struct called "Armor" and I want to use the name variable in the struct to have the path to whatever the name is.

struct Armor {
    bool equipped;
    std::string name;

    int getBuff(int buff) {
        std::fstream item;
        std::string line;
        std::string response;
        std::string value;

        item.open("../Data/Items/" + name + ".item", std::fstream::in);
        if (item.fail())
            errorQuit("ERROR: There was a problem loading armor type .ITEM file."); // Error and quit function

        while (!item.eof()) {
            getline(item, line);
            response = split(line, '=', 0); // Splits string
            if (response == "buff" + std::to_string(buff)) {
                value = split(line, '=', 1);
                break;
            }
        }

        item.close();
        return std::stoi(value);
    }

};

Then I called it like this:

Armor sword;
    sword.name = "Wooden Sword";
    int buff = sword.getBuff(1);

But this throws an Unhandled exception error. I changed it so that getBuff takes 2 parameters, int buff and std::string itemName. and replaced name in the path with itemName; Then I tried calling it like this:

Armor sword;
    sword.name = "Wooden Sword";
    int buff = sword.getBuff(1, sword.name);

But this throws the same error.

I'm confused as to why I can't use the name variable as it has already be defined. Is there any other way I can use the name variable like that?

Lunatoid
  • 1
  • 3
  • 1
    The problem is not the variable `name`. – deviantfan Oct 18 '15 at 15:54
  • 1
    Is the file content important? If yes, please provide the content or mock it using a stringstream. If not, remove that part to get closer to a minimal example. Also, variable names are something that doesn't exist any more after compilation to binary code, but the exception is raised while running the binary, so your guess that the variable name may be related is unfounded. – Ulrich Eckhardt Oct 18 '15 at 15:56
  • What does the split function do? Please post it's code. – Algirdas Preidžius Oct 18 '15 at 16:29
  • With a debugger you could immediately see which part of the code throws the exception. – Christian Hackl Oct 18 '15 at 16:31

3 Answers3

1

I see you've just edited your comment to say you've figured your problem out, but I just want to add something else that may be helpful:

Without seeing how errorQuit() is defined, there's a potential problem in your getBuff() function. If the expression if (item.fail()) evaluates to true, the function may continue on trying to process the data (unless errorQuit() somehow breaks out of the program or something, which probably isn't the best approach).

Basically, testing for fail() may or may not provide the behavior you require in all scenarios, depending on what bits are set in the stream state. Implementations vary, but... if the file fails to open, failbit and/or badbit will be set, but not eofbit. getline() will see the error state and so it will not try to read from the stream when you call it. But that also means the eofbit will never be set!

There's lots of different "techniques" to file reading. Some people prefer an RAII approach. Others like looping on getline(). Or you could even just use good() to check the error state if you don't care what happened and simply want to know if everything is fine or not.

In any case, you might be interested in the info on this page: std::ios_base::iostate.

Dan
  • 333
  • 4
  • 12
  • The errorQuit program just takes a string, displays it, wait for the user to press any key and then quits the program with exit(1) – Lunatoid Oct 19 '15 at 16:40
  • @Lunatoid Ah, ok. I don't want to get off-topic here, but I'd be a bad person if I didn't at least mention that many programmers scoff at using exit(). So I'll just refer you to [this helpful post](http://stackoverflow.com/a/30251056/5460182). When programs get more complicated, things can get messy if there's multiple places where the program can terminate. – Dan Oct 20 '15 at 00:24
0

Thanks for all your help but I figured it out on my own.

I just made a stupid error that I overlooked like an idiot.

It is searching for buff + int (e.x. buff1) in the file but there are multiple lines that contain that word so I guessed that messed it up. I just made an adjustment to the if statement and it is working as expected.

Sorry to bother you!

Lunatoid
  • 1
  • 3
-2

your getBuf() function fails on some io-operation and throws an exception.You dont handle exceptions and thus the application quits with the appropriate message. Try surrounding the call to getBuf with try/catch (add the includes to iostream and stdexcept)

try {
  int buff = sword.getBuff(1);
}
catch (const std::exception &e) {
  std::cout << e.what() << std::endl;
}
Norbert Lange
  • 1,162
  • 1
  • 10
  • 15
  • 1
    But, the problem is, when fstreams fail doing IO operations - they only set internal failure flags, which you can retrieve via methods. They don't throw exceptions. – Algirdas Preidžius Oct 18 '15 at 16:28
  • It throws an exception if open fails, and could be configured to throw in other circumstances. The key point is, that the app fails because of an unhandled exception and a handler will provide some insight – Norbert Lange Oct 18 '15 at 18:31
  • But, you have to manually configure ifstream to throw exceptions. It doesn't do that by default. If the OP did manually configure ifstream to throw exceptions, I assume that would've been the first place he would look into. – Algirdas Preidžius Oct 18 '15 at 19:47