2010-11-15 8 views
0

Je l'extrait de code de code suivant qui fonctionne très bien:Comment puis-je lire un contenu en ligne de fichier en utilisant le numéro de ligne

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

Mais le problème est que je dois mettre à jour un état de case à cocher en comparant les valeurs de ligne. Le code sera alors similaire à ce qui suit:

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 
      } 
     } 

Si je vais utiliser while alors mon état sera plus RIDEN que la dernière de la valeur de la boucle ou de l'État sera mis à jour. Y a-t-il un autre moyen de s'en sortir? J'ai besoin de définir les valeurs de la case à cocher après avoir lu le fichier de configuration. Le fichier de configuration se présente comme ci-dessous:

AutoStart = 0
AutLogHistory = 1
AutoScan = 1
AutoMount = 0
AutoOpen = 0
LastConnectedSvr = 1

Bien que je peux J'ai seulement un seul si et tout le reste comme d'autres si cela peut aider mais j'ai besoin d'un meilleur moyen.

+1

Il n'est pas clair quel est le problème. Voulez-vous que le premier paramètre pour vos variables dans NDS.config "compte"? Voulez-vous vérifier les variables doublement définies dans le fichier? Qu'est-ce que cela a à voir avec les numéros de ligne que vous mentionnez dans le titre? –

Répondre

3

Alternativement, utilisez boost::program_options, ceci est conçu parfaitement pour ce dont vous avez besoin!

EDIT: un peu plus de détails, program_options a une méthode pour analyser un fichier de configuration, comme le vôtre, et lorsque vous configurez program_options, vous pouvez passer dans la variable pour stocker la valeur du fichier de configuration. leur exemple simple, il deviendra abondamment clair ...

L'autre option est pour vous de stocker vos clés dans une carte, avec une valeur par défaut de 0, et alors que vous analysez votre fichier, placez la clé à la valeur lue à partir du fichier ...

EDIT:

en utilisant les options du programme (ce qui est code non testé, s'il vous plaît essayer reportez-vous à la documentation et corriger au besoin!)

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); 

Lorsque ce lot fonctionne, les différents entiers auront les valeurs du fichier (ou être en défaut à 0). La bonne chose avec cette approche est que vous pouvez avoir différents types dans vos fichiers de configuration, et tant qu'ils sont formatés en fichiers INI, alors cela fonctionnera.

L'autre approche utilisant std :: carte, bien @ Moo-Juice a déjà ajouté le code de travail ...

+0

Si vous pouvez élaborer un peu s'il vous plaît – Simsons

+0

@Subhen, élaborer sur quel bit? – Nim

+0

Si vous avez un exemple de fragment de code. Je ne trouve pas un moyen d'utiliser dans mon code – Simsons

1

Vous pouvez utiliser boost program arguments parser avec spécifiquement config file parser pour obtenir tous les arguments du programme.

C'est l'exemple de boost (petites modifications sont les miennes):

#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 << "\n"; 
      return 0; 
     } 
     else 
     { 
      store(parse_config_file(ifs, config_file_options), vm); 
      notify(vm); 
     } 

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

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

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

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

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


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

Le problème que vous rencontrez est votre logique de lecture ces lignes dans.Vous pouvez utiliser boost :: program_options comme mentionné plus haut, ou même une sorte de lecteur xml, mais pour une solution rapide et sale à votre problème:

#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; 
     }; 
    }; 
    } 

Maintenant, à la fin, la carte contient les valeurs de la valeurs du fichier en eux. Vous pouvez les parcourir et faire ce que vous aimez avec eux.

Questions connexes