简体   繁体   中英

How to read = separated data from file

I have a data file that contains key value pairs separated by an = character.

Example data file is like below.

A = 1 
B = 2
C = 3 
D = 4

I want to read only some keys from the data file. For example, I only want to read A and C keys in this example. I used a for loop and getline to do this but unable to get data.

Below is the MWE.

#include <string>
#include <sstream>
#include <iomanip>
#include <iostream>

// pretend file stream
std::istringstream data(R"(
A = 0.0000
B = 1.0000
C = 2.0000
D = 3.0000
)");

int main()
{

    double A, C;
    
    for(std::string key; std::getline(data, key, '='); ){
        std::cout << key << "Printed Key." << std::endl;
        if(key == "A "){
            data >> A;
            std::cout << A << std::endl;
        }
        else if(key == "C "){
            data >> C;
            std::cout << C << std::endl;
        }
    }

}

For some reason when I print the key, Its giving the following output. Instead of reading from where it left off.

A Printed Key.
 0.0000
B Printed Key.
 1.0000
C Printed Key.
 2.0000
D Printed Key.
 3.0000
Printed Key.

Starting from the second getline() , the key value will be what is left in the line of the previous called until the next = in the following line. This example will make it easier to understand.

#include <string>
#include <sstream>
#include <iomanip>
#include <iostream>

// pretend file stream
std::istringstream data("A = 0.0000\n"
                        "B = 1.0000\n"
                        "C = 2.0000\n"
                        "D = 3.0000\n");

int main()
{

    double A, C;
    
    for(std::string key; std::getline(data, key, '='); ){
        std::cout << key << "Printed Key." << std::endl;
        if(key == "A "){
            data >> A;
            std::cout << A << " A value printed" << std::endl;
        }
        else if(key == " 1.0000\nC "){
            data >> C;
            std::cout << C << " C value printed" << std::endl;
        }
    }

}

You can add another getline() at the end of each loop to get the rest of the line and the code will work

#include <string>
#include <sstream>
#include <iomanip>
#include <iostream>

// pretend file stream
std::istringstream data("A = 0.0000\n"
                        "B = 1.0000\n"
                        "C = 2.0000\n"
                        "D = 3.0000\n");

int main()
{

    double A, C;
    
    for(std::string key; std::getline(data, key, '='); ){
        std::cout << key << "Printed Key." << std::endl;
        if(key == "A "){
            data >> A;
            std::cout << A << " A value printed" << std::endl;
        }
        else if(key == "C "){
            data >> C;
            std::cout << C << " C value printed" << std::endl;
        }
        std::getline(data, key);
    }

}

This looks like ini file or part of it. So instead reinventing the wheel it is better to use ready solution like boost.

#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>

int main()
{
    using namespace boost::property_tree;
    ptree values;
    ini_parser::read_ini(std::cin, values);
    std::cout << values.get<double>("A") << '\n';
    std::cout << values.get<double>("B") << '\n';
    std::cout << values.get<double>("C") << '\n';
    std::cout << values.get<double>("D") << '\n';

    return 0;
}

https://godbolt.org/z/7s9d57

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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