-1

I have a file of this type:

key1#value1#value2##
key2#value3#value4#value5##
key3#value6##
etc.

I need to read each line, and separate key and values. I've tried different approaches (istringstream & iterator - but I don't know how to explicitly define # as the separator), double getline, I read about boost libraries but I am not sure I would be able to compile it.

I thought another way to do it would be to separate each line into a vector. The first element will always be the key, and vector's size will determine how many values each line had.

What is the best way to split each line?

  • This question already has an answer http://stackoverflow.com/questions/3946558/c-read-from-text-file-and-separate-into-variable – Tejendra Mar 09 '15 at 08:44
  • @Tejendra Incorrect. The mentioned answers does not cover custom delimiter settings, which is in fact the question here. – Géza Török Mar 09 '15 at 08:49
  • @Tejendra, the question you linked only provides an answer if the file format uses a value separator (`s`) for which `std::isspace(s)` evaluates to true (tokens separated by spaces, tabs, etc). – utnapistim Mar 09 '15 at 08:51
  • Hey, SO people! Why do you downvote _every_ _single_ question regardless of it's worthy or not? I simply don't get why a question about delimiter usage with C++ streams deserve a downvote.. – Géza Török Mar 09 '15 at 08:51

2 Answers2

5

What is the best way to split each line?

I would simply call while(std::getline(stream, line) to read each line, then for each read line, I would put it into a istringstream (iss), and call while(std::getline(iss, value, '#')) repeatedly (with stream being your initial stream, and line and value being strings). The first value read in the inner loop will be the key; the rest, will be the values.

Some code:

auto read_file(std::istream& in)
{
    using namespace std;
    map<string, vector<string>> values;
    string line;
    while(getline(in, line))
    {
        istringstream linein{ line };
        string key, value;
        if(!getline(linein, key, '#'))
            throw runtime_error{ "bad file format" };
        while(getline(linein, value, '#') && !value.empty())
            values[key].emplace_back(move(value));
    }
    return values;
}

std::ifstream in{ "file-of-this-type.txt" };
auto values = read_file(in);
utnapistim
  • 26,809
  • 3
  • 46
  • 82
0

You can get each line as a String. After that use this information Split a string in C++? It's very useful

Community
  • 1
  • 1
acostela
  • 2,597
  • 3
  • 33
  • 50