Search code examples
c++ifstreamstdstring

M_construct error when reading file contents


I'm creating a game that requires a lot of setup. I decided to add a configuration file (.ini) and a reader to get the information. My ini file is setup as follows:

-cmd arg0 arg1

I initially only had one command which worked fine until I added a second. For whatever reason, I receive an std::logic_error when my command is not the first one.

// this works
-load w "someName"

// this doesn't
-delete "someName"

Here is the code used to read the file:

InitFileReader::InitFileReader()
{
    std::string ini_file_path = "";
    ini_file_path += PROGRAM_FOLDER;
    ini_file_path += "\\blockgame.ini";
    std::ifstream ini_file(ini_file_path);

    if (!ini_file.is_open()) std::cout << "Couldn't find configuration file at " << ini_file_path << std::endl;

    std::string line;

    while(std::getline(ini_file, line))
    {
        if (starts_with(line, "-load "))
        {
            std::string arg0 = "";

            unsigned int index = 6;
            for (; index < line.size(); index++)
            {
                char c = line[index];
                if (c == ' ') break;

                arg0 += c;
            }

            std::string arg1 = "";
            bool reached_quote = false;

            for (; index < line.size(); index++)
            {
                char c = line[index];
                if (c == ' ' && !reached_quote) continue;

                if (c == '\"' && !reached_quote)
                {
                    reached_quote = true;
                    continue;
                }
                else if (c == '\"') break;

                arg1 += c;
            }

            sfr = new SaveFolderReader(arg1);

            if (arg0 == "new")
            {
                sfr->new_header(DEFAULT_HEADER);
            }
            else if (arg0 == "def")
            {
                sfr->restore_header(DEFAULT_HEADER);
            }
        }
        else if (starts_with(line, "-delete "))
        {
            std::string arg0 = "";

            unsigned int index = 8;
            for (; index < line.size(); index++)
            {
                char c = line[index];
                if (c == ' ') break;

                arg0 += c;
            }

            std::string world_path = "";
            world_path += PROGRAM_FOLDER;
            world_path += "\\save\\";
            world_path += arg0;

            if (rmdir(world_path.c_str()) != 0)
            {
                std::cout << "Error deleting world \"" << arg0 << "\"" << std::endl;
            }
        }
    }
}

inline bool starts_with(const std::string& target, const std::string& prefix)
{
    if (target.size() < prefix.size())
        return false;

    for (unsigned int i = 0; i < prefix.size(); i++)
    {
        if (target[i] != prefix[i])
            return false;
    }

    return true;
}

The PROGRAM_FOLDER constant is just the parent folder of the path returned by argv[0] in main. I can't run the debugger on this code because the path changes to something strange when I do that.

I know that this error shows up because of a nullptr initialization of std::string but I still have no idea why this is happening.

I've tried typing in random characters into the config file and get the same result. It baffles me that the first if-statement works fine but the second one doesn't (when I use the -delete command).

Any suggestions would be of great use, thanks in advance!


Solution

  • It turns out that the error wasn't coming from that block of code at all. What was happening was that my game tried to load data in afterwards but because I didn't write the load command there was nothing to read from. I fixed my Debugger issue (For whatever reason the char[] I allocated stored different data when the debugger ran) and just reverted to std::strings.