c ++ - Hvordan kan jeg læse et fillinjeindhold ved hjælp af linjenummer

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har følgende kodestykke, der fungerer fint:


 ifstream NDSConfig( "NDS.config" ) ;
        string szConfigVal ;
        while( getline( NDSConfig, szConfigVal ) )
        {
            //code
        }


Men problemet er, at jeg skal opdatere en afkrydsningsfelt tilstand ved at sammenligne linjeværdierne. Koden derefter svarer til følgende:


 ifstream NDSConfig( "NDS.config" ) ;
        string szConfigVal ;
        while( getline( NDSConfig, szConfigVal ) )
        {
            if(szConfigVal == "AutoStart = 1")
            {
                      //Set Check Box True
            }
            else if(szConfigVal == "AutoStart = 0")
            {
                      //Set Check Box False
            }

            if(szConfigVal == "AutLogHistory = 1")
            {
                      //Set Check Box True
            }
            else if(szConfigVal == "AutLogHistory = 0")
            {
                      //Set Check Box False
            }

            if(szConfigVal == "AutoScan = 1")
            {
                      //Set Check Box True
            }
            else if(szConfigVal == "AutoScan = 0")
            {
                      //Set Check Box False
            }

            if(szConfigVal == "AutoMount = 1")
            {
                      //Set Check Box True
            }
            else if(szConfigVal == "AutoMount = 0")
            {
                      //Set Check Box False
            }

            if(szConfigVal == "AutoOpen = 1")
            {
                      //Set Check Box True
            }
            else if(szConfigVal == "AutoOpen = 0")
            {
                      //Set Check Box False
            }

            if(szConfigVal == "LastConnectedSvr = 1")
            {
                      //Set Check Box True
            }
            else if(szConfigVal == "LastConnectedSvr = 0")
            {
                      //Set Check Box False
            }
        }


Hvis jeg skal bruge mens sløjfen, så vil min tilstand være over riden og kun sidste i sløjfeværdien eller tilstanden vil blive opdateret. Er der nogen anden vej ud. Jeg skal sætte afkrydsningsfeltet værdier efter at have læst fra config fil. Config-filen ser ud som nedenfor:



  AutoStart=0

  AutLogHistory=1

  AutoScan=1

  AutoMount=0

  AutoOpen=0

  LastConnectedSvr=1



Selvom jeg kun kan have single hvis og alt andet ellers hvis det vil hjælpe, men jeg har brug for en bedre måde.

Bedste reference


Alternativt kan du bruge boost::program\_options, det er perfekt til det, du har brug for!


EDIT: lidt mere detaljeret, program\_options har en metode til at analysere en config-fil som din, og når du konfigurerer program\_optioner, kan du passere i variablen for at gemme værdien fra config-filen. Se på deres enkle eksempel, det bliver rigeligt klart ...


En anden mulighed er, at du gemmer dine nøgler i et kort med en standardværdi på 0, og derefter, når du analyserer din fil, skal du indstille nøglen til den værdi, du læser fra filen ...


REDIGERE:


ved hjælp af programindstillinger (dette er uprøvet kode, prøv venligst at se dokumentationen og rette efter behov!)


int AutoStart;
int AutLogHistory;
int AutoScan;
int AutoMount;
int AutoOpen;
int LastConnectedSvr;

po::options\_description desc("Allowed options");
desc.add\_options()
    ("help", "produce help message")
    ("AutoStart", po::value<int>(&AutoStart)->default\_value(0),"AutoStart")
    ("AutLogHistory", po::value<int>(&AutLogHistory)->default\_value(0),"AutLogHistory")
    ("AutoScan", po::value<int>(&AutoScan)->default\_value(0),"AutoScan")
    ("AutoMount", po::value<int>(&AutoMount)->default\_value(0),"AutoMount")
    ("AutoOpen", po::value<int>(&AutoOpen)->default\_value(0),"AutoOpen")
    ("LastConnectedSvr", po::value<int>(&LastConnectedSvr)->default\_value(0),"LastConnectedSvr")
;

std::ifstream config("NDS.config");

po::parse\_command\_line(config, desc, true);


Når dette parti kører, vil de forskellige heltal have værdierne fra filen (eller være standard til 0).


Den pæne ting med denne tilgang er, at du kan have forskellige typer i dine config-filer, og så længe de er formateret som INI-filer, fungerer dette.


Den anden tilgang ved hjælp af std :: map, godt @ Moo-Juice har allerede tilføjet arbejds kode ...

Andre referencer 1


Det problem du har er med din logik for at læse disse linjer. Du kunne bruge boost :: program\_options som nævnt før, eller endda en slags xml-læser, men for en hurtig og beskidt løsning på dit problem:


#include <string>
#include <map>
#include <algorithm>

// typedef some stuff so our fingers don't die.
typedef std::map<std::string, bool> CheckMap;
typedef CheckMap::iterator CheckMap\_it;
typedef std::pair<std::string, bool> CheckPair;

std::string szKey, szVal;
// declare our map that will store the state
CheckMap map;


// insert possible config values
map.insert(CheckPair("AutoStart", false));
map.insert(CheckPair("AutLogHistory", false));
map.insert(CheckPair("AutoScan", false));
map.insert(CheckPair("AutoMount", false));
map.insert(CheckPair("AutoOpen", false));
map.insert(CheckPair("LastConnectedSvr", false));

// now loop through the file
ifstream NDSConfig( "NDS.config" ) ;
    string szConfigVal ;
    while( getline( NDSConfig, szConfigVal ) )
    {
        // erase any spaces in the line
    szConfigVal.erase(std::remove\_if(szConfigVal.begin(), szConfigVal.end(), isspace), szConfigVal.end());

        // locate equals, split in to <key> <value> using that.
        std::string::size\_type equals(szConfigVal.find('='));
    if(equals != std::string::npos) // exists?
    {
        szKey = szConfigVal.substr(0, equals);
        szVal = szConfigVal.substr(equals + 1);

        // locate key and set value
        CheckMap\_it it(map.find(szKey));
        if(it != map.end()) // sanity check
        {
        // could use a boost-type cast here, but I'm keeping it simple
        it->second = (szVal == "1") ? true : false;
        };
    };
    }


Nu, i slutningen, indeholder kortet værdierne med værdierne fra filen i dem. Du kan iterere gennem dem og gøre, hvad du kan lide med dem.

Andre referencer 2


Du kan bruge boost program argumenter parser med specifikt config fil parser for at få alle program argumenter. [7] [8]


Dette er eksemplet fra boost (små ændringer er mine):


#include <boost/program\_options.hpp>
namespace po = boost::program\_options;


#include <iostream>
#include <fstream>
#include <iterator>
using namespace std;

// A helper function to simplify the main part.
template<class T>
ostream& operator<<(ostream& os, const vector<T>& v)
{
    copy(v.begin(), v.end(), ostream\_iterator<T>(cout, " "));
    return os;
}


int main(int ac, char* av[])
{
        std::cout<<av[0]<<std::endl;

std::vector<std::string> incsss;
std::vector<std::string> filsss;

    try {
        int opt;
        string config\_file;

        // Declare a group of options that will be
        // allowed only on command line
        po::options\_description generic("Generic options");
        generic.add\_options()
            ("version,v", "print version string")
            ("help,h", "produce help message")
            ("config,c", po::value<string>(&config\_file)->default\_value("multiple\_sources.cfg"),
                  "name of a file of a configuration.")
            ;

        // Declare a group of options that will be
        // allowed both on command line and in
        // config file
        po::options\_description config("Configuration");
        config.add\_options()
            ("optimization", po::value<int>(&opt)->default\_value(10),
                  "optimization level")
            ("include-path,I",
              po::value< vector<string> >(&incsss)->composing(),
                 "include path")
            ;

        // Hidden options, will be allowed both on command line and
        // in config file, but will not be shown to the user.
        po::options\_description hidden("Hidden options");
        hidden.add\_options()
        ("input-file", po::value< vector<string> >(&filsss), "input file")
            ;


        po::options\_description cmdline\_options;
        cmdline\_options.add(generic).add(config).add(hidden);

        po::options\_description config\_file\_options;
        config\_file\_options.add(config).add(hidden);

        po::options\_description visible("Allowed options");
        visible.add(generic).add(config);

        po::positional\_options\_description p;
        p.add("input-file", 3);

        po::variables\_map vm;
        store(po::command\_line\_parser(ac, av).
              options(cmdline\_options).positional(p).run(), vm);
        notify(vm);

        ifstream ifs(config\_file.c\_str());
        if (!ifs)
        {
               cout << "can not open config file: " << config\_file << "
";
            return 0;
        }
        else
        {
            store(parse\_config\_file(ifs, config\_file\_options), vm);
            notify(vm);
        }

        if (vm.count("help")) {
            cout << visible << "
";
            cout<<"here"<<std::endl;
            return 0;
        }

        if (vm.count("version")) {
            cout << "Multiple sources example, version 1.0
";
            return 0;
        }

        if (vm.count("include-path"))
        {
            cout << "Include paths are: "
                 << vm["include-path"].as< vector<string> >() << "
";
        }

        if (vm.count("input-file"))
        {
            cout << "Input files are: "
                 << vm["input-file"].as< vector<string> >() << "
";
        }

        cout << "Optimization level is " << opt << "
";


        cout << "incsss constains : " <<incsss << std::endl;
        cout << "filsss constains : " <<filsss << std::endl;
    }
    catch(exception& e)
    {
        cout << e.what() << "
";
        return 1;
    }
    return 0;
}