user1777711
user1777711

Reputation: 1744

Manipulate Input File Stream

I have a data text file which contains this

Map2D, [3, 2]
Dot3D, [25, -69, -33], [-2, -41, 58]
Map3D, [6, 9, -50]
Map2D, [3, 2]
Dot3D, [7, -12, 3], [9, 13, 68]
Map3D, [6, 9, 5]
Map2D, [3, 2]
Dot3D, [70, -120, -3], [-29, 1, 268]
Dot3D, [7, 12, 3], [-9, 13, 68]
Map3D, [1, 3, 8]
Dot2D, [5, 7], [3, 8]

Basically the text file first data is the class name which i got 4 class

Map2D
Map3D
Dot2D
Dot3D

I was trying to write my own file manipulator so that my program can extract the data above and overload the extraction operator >> for each of the 4 class and then storing it into relevant object.

I was thinking of using vector, map, set or list to store . but for this how do i achieve what i want to do such as store into relevant object of the class.

I tried googling around on how to create my own file manipulator, but will be good if someone could show me some sample code and i can compile and execute it maybe in a test file then observe the output myself. I would like to use iomanip to do a overload on the >> operator

I have to use manipulator because i need create something like

I need to do something like

cout << "Input File Name";
cin >> readFile;

and perform all the data reading & object creation

I am sorry for all the trouble caused. then it will read the records line by line, then create the class and also the data in it.

Thanks for all your help!

Upvotes: 1

Views: 707

Answers (2)

andre
andre

Reputation: 7249

This is an example with std::cin. It should work just fine with a fstream. parsing your input is really nasty. Is it possible to remove the brackets("[" amd "]") from the input?

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
#include <c>

class Map2D {
    std::vector<int> values;
public:
    friend std::istream& operator>>(std::istream& in, Map2D m) {
        std::string i;
        in >> i;
        std::stringstream ss(i);
        std::getline(ss, i, '[');
        std::getline(ss, i, ',');
        ss >> i;
        std::cout << i << std::endl;
        in >> i;
        ss.str("");
        ss << i;
        i = i.substr(0, i.size()-1);
        ss >> i;
        std::cout << i << std::endl;;
    }
};

int main() {
    std::string type, file_name;
    std::cout << "Input File Name";
    std::cin >> file_name;
    std::fstream file(file_name.c_str());
    Map2D m;
    while (std::getline(std::cin, type, ',')) {
        if(type.find("Map2D") != std::string::npos) {
            file >> m;
        }
    }
}

Upvotes: 4

pstrjds
pstrjds

Reputation: 17428

You can use the cin to get the filename, but then you should write a helper method that can parse the file.

My suggestion would be to create a class called DataMembers or something like that. In that class you can have a helper method that reads in a data member file. The class could have 4 vectors for storing the data you read from the file.

class DataMembers
{
    private:
        std::vector<Map2D> _map2Ds;
        std::vector<Map3D> _map3Ds;
        ....
    public:
        void readDataFile(std::string inFileName);
        void writeDataFile(std::string outFileName);
};

The readDataFile method should do the following

  1. Read the file in a line at a time
  2. Parse the line to determine the object type to create (error out if the type is not recognized)
  3. Validate that the line contains the correct data for the type indicated
  4. Create the object of the proper type
  5. Assign the object to the proper object collection

You would probably want to write some other private methods to handle the creation of the data types and assigning to the proper collections.

Upvotes: 3

Related Questions