Question

Basicly I have a text file which i need t read-in the values so the program can manipulate them.

Im using C++ and i have written working code to tell if the file exists or not.

The text file is formatted like this:

1    7
8    10
20   6
3    14
...

The values on the left are X values and the values on the right are Y values. (The space in the middle is a tab) How do I extract this data? say to pass them into a class like this...

myVector(X,Y);

Also, I guess before I can use it in a class I have to TryParse to change it from a string to int right? can C++ do this?

Thank you!

Was it helpful?

Solution

I would be writing something like this if I were you. Note, this is just prototype code, and it was not even tested.

The fundamental idea is to read twice in a line, but with different delimiters. You would read with the tab delimiter first, and then just the default line end.

You need to make sure to gracefully quit the loop when you do not have anything more to read, hence the breaks, albeit the second could be enough if your file is "correct".

You will also need to make sure to convert to the proper type that your vector class expects. I assumed here that is int, but if it is string, you do not need the conversion I have put in place.

#include <string>
#include <fstream>

using namespace std;

void yourFunction()
{
    ..
    ifstream myfile("myfile.txt");
    string xword, yword;
    while (1) {
        if (!getline(myfile, xword, '\t'))
            break;
        if (!getline(myfile, yword))
            break;
        myVector.push_back(stoi(xword), stoi(yword));
    }
    ...
}

OTHER TIPS

This sort of parsing could be done in one line with boost.spirit:

qi::phrase_parse(begin, end, *(qi::int_ > qi::int_ > qi::eol), qi::ascii::blank, v);

The grammar could be read as: "read one int, then one int, then one EOL (end of line) (\n or \r\n, depends on locale), as many time as possible". Between ints and EOL can be found blank characters (e.g. spaces or tabs).

Advantages: rather than std::getline loops, code is more clear/concise. spirit.qi get you more powerful control and you don't need stoi calls. Drawbacks: build-depends (no depends) to spirit.qi, compilation time.

#include <iostream>
#include <fstream>
#include <vector>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/std_pair.hpp>

namespace spirit = boost::spirit;
namespace qi = spirit::qi;

int main(int argc, char **argv)
{
  std::ifstream in(argv[1], std::ios_base::in);

  std::string storage;
  in.unsetf(std::ios::skipws);
  spirit::istream_iterator begin(in), end;

  std::vector<std::pair<int, int> > v;
  qi::phrase_parse(begin, end, *(qi::int_ > qi::int_ > qi::eol), qi::ascii::blank, v);

  for(const auto& p : v)
    std::cout << p.first << "," << p.second << std::endl;

  return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top