简体   繁体   English

如何使用行号读取文件行内容

[英]How can I read a file line content using line number

I have the following code snippet which is working fine: 我有以下工作正常的代码段:

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

But the problem is I need to update a check box state by comparing the line values. 但是问题是我需要通过比较行值来更新复选框状态。 The code then will similar to the following: 然后,代码将类似于以下内容:

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

If I am going to use while loop then my state will be over riden and only last in the loop value or state will be updated. 如果我要使用while循环,那么我的状态将被超越,并且仅循环中的最后一个值或状态将被更新。 Is there any other way out. 还有其他出路吗? I need to set the check box values after reading from config file . 从配置文件读取后,我需要设置复选框值。 The Config file looks as below: 配置文件如下所示:

AutoStart = 0 自动启动= 0
AutLogHistory = 1 AutLogHistory = 1
AutoScan = 1 自动扫描= 1
AutoMount = 0 自动挂载= 0
AutoOpen = 0 自动开启= 0
LastConnectedSvr = 1 LastConnectedSvr = 1

Though I can have only single if and everything else as else if will help but I need a better way. 虽然我只能拥有一个if,否则其他一切都将有所帮助,但是我需要一个更好的方法。

Alternatively, use boost::program_options , this is designed perfectly for what you require! 或者,使用boost::program_options ,它完全适合您的需求!

EDIT: little more detail, program_options has a method to parse a config file, such as yours, and as you configure program_options, you can pass in the variable to store the value from the config file in. Have a look at their simple example, it will become abundantly clear... 编辑:更多细节,program_options具有解析配置文件(例如您的配置文件)的方法,并且在配置program_options时,您可以传入变量以将配置文件中的值存储在其中。看看它们的简单示例,它将变得非常清晰...

Other option is for you to store your keys in a map, with a default value of 0, and then as you parse through your file, set the key to the value you read from the file... 另一个选项是将密钥存储在地图中,默认值为0,然后在解析文件时,将密钥设置为从文件读取的值...

EDIT: 编辑:

using program options (this is untested code, please try refer to the documentation and fix as needed!) 使用程序选项(这是未经测试的代码,请尝试参考文档并根据需要进行修复!)

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

When that lot runs, the various integers will have the values from the file (or be defaulted to 0). 当该批次运行时,各种整数将具有文件中的值(或默认为0)。

The neat thing with this approach is that you can have different types in your config files, and as long as they are formatted as INI files, then this will work. 这种方法的好处是,您可以在配置文件中使用不同的类型 ,并且只要将它们格式化为INI文件,就可以使用。

The other approach using std::map, well @Moo-Juice has already added working code... 使用std :: map的另一种方法,@ Moo-Juice已经添加了工作代码...

The problem you're having is with your logic of reading this lines in. You could use boost::program_options as mentioned before, or even some kind of xml reader, but for a quick and dirty solution to your problem: 您遇到的问题是读入这些行的逻辑。您可以使用前面提到的boost :: program_options,甚至可以使用某种xml阅读器,但是可以快速而又肮脏地解决您的问题:

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

Now, at the end, the map holds the values with the values from the file in them. 现在,最后,映射将值与文件中的值一起保存。 You can iterate through them and do what you like with them. 您可以遍历它们,并对它们执行自己喜欢的操作。

You can use boost program arguments parser with specifically config file parser to get all program arguments. 您可以使用boost程序参数解析器和专门的配置文件解析器来获取所有程序参数。

This is the example from boost (small modifications are mine) : 这是boost的示例(我做了一些小的修改):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM