[C++] Boost::program_options: config file lesen

bad_alloc

Member of Honour
Hallo HaBo,
ich versuche momentan mit C++ und mit dem in Boost 1.40.00 enthaltenen program_options eine Konfiguartionsdatei zu lesen. Jetzt habe ich das Problem, dass folgender Funktiosnaufruf die Exception invalid_syntax wirft:
Code:
namespace po = boost::program_options;
po::store(po::parse_config_file(configFile, config), config_map);
//configFile ist ein std::string mit dem Pfad zur config-Datei. Der Pfad ist nachweislich valide.
Also ist meine Konfigurationsdatei wohl ungültig. Momentan sieht sie so aus:
Code:
x_size = 1280
y_size = 800
max_fps = 50
background_color = 255 255 255
Da in der Boost-Dokumentation keinerlei Beispiele zu finden sind, habe ich die Datei eine .ini Datei nachempfunden. Wie muss der Syntax richtigerweise lauten?

Code:
void parseCommandLineArguments(int argumentCount, char* argumentVector[], std::string* textureFile, std::string* saveFile,
                               int* X_Resolution, int* Y_Resolution, int* fps, int* red, int* green, int* blue) {
    std::stringstream configFile;
    configFile << "conf.conf";


    // Declare the supported options for the CLI
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "produce help message")
        ("texturefile", po::value<string>(), "specify the .res file to use for texturing")
        ("savefile", po::value<string>(), "specify the save file to load")
        ("config", po::value<string>(), "specify the config file, default is conf.conf")
    ;

    //options for the config file
    po::options_description config("Configuration");
    config.add_options()
        ("x_size", po::value<int>(), "Horizontal size of render window")
        ("y_size", po::value<int>(), "vertical size of render window")
        ("max_fps", po::value<int>(), "Frame rate limit")
        ("background_color", po::value<vector<int> >(), "Background colors as RGB triplet")
    ;

    try {
        //parse and store the comamndline stuff
        po::variables_map cli_map;
        po::store(po::parse_command_line(argumentCount, argumentVector, desc), cli_map);
        po::notify(cli_map);

        //handle help request
        if(cli_map.count("help")) {
            cout << desc << "\n";
            return;
        }
        // find texture file and check validity
        if(cli_map.count("texturefile")) {
            *textureFile = cli_map["texturefile"].as<string>();
        } else {
            cout << "Assuming default texturefile." << endl;
            *textureFile = "texturefile.res";
        }
        if(!boost::filesystem::exists(*textureFile)) {
            cerr << "The texture file \" " << *textureFile << "\"does not exist (or at least cannot be found). Aborting." << endl;
            exit(-1);
        }

        //now the savefile, also check if it exists
        if(cli_map.count("savefile")) {
            *saveFile = cli_map["savefile"].as<string>();
        } else {
            cout << "No save file specified. Terminating." << endl;
            exit(-1);
        }
        if(!boost::filesystem::exists(*saveFile)) {
            cerr << "The save file \"" << *saveFile << "\" does not exist (or at least cannot be found). Aborting." << endl;
            exit(-1);
        }

        //find out the path to the config file
        if(cli_map.count("config")) {
            configFile << cli_map["config"].as<string>();
        } else {
            cout << "Assuming default config file: " << configFile.str() << endl;
        }
        if(!boost::filesystem::exists(configFile.str())) {
            cerr << "The config file \"" << configFile.str() << "\" does not exist (or at least cannot be found). Aborting." << endl;
            exit(-1);
        }

        //now we should have a config file
        po::variables_map config_map;
        po::store(po::parse_config_file(configFile, config), config_map);
        po::notify(config_map);

        //read data from config file whilst checking for illegal inputs
        if(config_map.count("x_size")) {
            try {
                *X_Resolution = config_map["x_size"].as<int>();
            } catch (...) {
                cerr << "Error whilst reading horizontal resolution. Assuming 1280" << endl;
                *X_Resolution = 1280;
            }
        }
        if(config_map.count("y_size")) {
            try {
                *Y_Resolution = config_map["y_size"].as<int>();
            } catch (...) {
                cerr << "Error whilst reading vertical resolution. Assuming 800" << endl;
                *Y_Resolution = 800;
            }
        }
        if(config_map.count("max_fps")) {
            try {
                *fps = config_map["max_fps"].as<int>();
            } catch (...) {
                cerr << "Error whilst reading maximum framerate. Assuming 50" << endl;
                *Y_Resolution = 50;
            }
        }
        if(config_map.count("background_color")) {
            try {
                vector<int> colors;
                colors = config_map["background_color"].as<vector<int> >();
                *red = colors[0];
                *green = colors[1];
                *blue = colors[2];
            } catch (...) {
                cerr << "Error whilst reading background color. Assuming white." << endl;
                *red = 255;
                *green = 255;
                *blue = 255;
            }
        }
    }
    catch(boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::program_options::unknown_option> > e) {
        cerr << e.what() << endl;
        exit(-1);
    }
    catch(boost::program_options::invalid_syntax e) {
        cerr << "Invalid syntax detected." << e.tokens << endl;
        exit(-1);
    }
    /*catch(...) {
        cerr << "Unknown error in the command line/config file parser." << endl;
        exit(-1);
    }*/
}

Gelöst: po::store(po::parse_config_file(configFile, config), config_map); → configFile darf kein stringstream sein, sondern muss ein ifstream sein. Merkwürdig, da stringstream eigentlich von fstream erbt.
 
Zuletzt bearbeitet:
Oben