Problem reading from class

I get an error-type problem from the following code from the data (ifstream class) variable. Hope someone can point out what is my wrong doing

#include <iostream>
#include <fstream>
#include <vector>

class Matrix{
public:
Matrix() {};
Matrix(std::string a) : path(a) {};


private:
std::string path,line;
unsigned int row_size,col_size;
std::ifstream data;

data.open(path); //here is where the error appears

};

1
2
3
4
5
6
private:
std::string path,line;
unsigned int row_size,col_size;
std::ifstream data;

data.open(path); //here is where the error appears 


This is your declaration of a classes private members. The individual functions and member variables the class has.

data.open(path); appears to be a function call. This makes no sense here. When will this code ever run?

Your class defintion is for you to define class members, and class functions. data.open(path); is neither and makes no sense at all here.

In other words: You can use that line within a function only.
you can set up your class to do this in the constructor, just like a file object, such that
Matrix m(filename); //create m and open the file all at once, kinda like ifstream f(filename) would do... change that constructor you wrote (this is just an idea)
Matrix(std::string a) {data.open(a);};
Last edited on
Keep it in one thread please.
You still need a function. All the above did was open the file, you did no read it yet. you can read it in the constructor, or in another function. What do you want to do? If you read in the constructor, it must self correct (eg as if ran default ctor) if the file is missing or corrupt, but you can table that until you are farther along.

maybe we need to back up.
a 'class' or 'struct' is a user defined TYPE, not code.
its on par with saying int x; in most regards. It may automatically run some code when created (the constructor) or destroyed (the destructor) but if you want that, you have to define it, and normally, you would not do 'real code' in those, just 'initialization' and 'de-initialization' type work. Reading a file into itself counts as init, and this is just good practice, not required (you can do a ton of stuff in the constructor, but by convention, it should only be init related for typical types).

though is is a TYPE, you can tie functions to it, just like ifstream is a type but it has a .open() function tied to it. This is what you need to do... you need to decide HOW your want your code to behave, and then put the executable statements inside a function (which may or may not be the constructor, depending on your design).

I am thinking you may need to read a tutorial on classes again and write a simple one (without files to begin with) to get some of the basics down. We can help you, but the basics are better written in a tutorial than a post. Also clarify what exactly you want the class to do, and we can show you a simple example / starting point.
Last edited on
Matrix(std::string a)

Makes sense if you write a friend ... operator>>(....) method (they're not 'functions' even though they are superficially the same thing.)
(operator<< as well?)

std::string a would be the file name, which might contain the row/col count - who knows - but you'll need it.

It's a bit clunky that way. The other way is to have a constructor
Matrix(int rows, int cols) because, whatever container you use the row/col info is fundamental to a matrix. After that then have a separate Matrix::read_from_file(...) method which makes use of the operator overloads.

A small point but the Matrix functionality is quite limited if integer input/arithmetic is adopted, generally. Double's would be better.

operator>> etc is covered in the tutorials here.

operator<<

Header:
1
2
void setPrinter(int = 12, int = 6);
friend std::ostream& operator<< (std::ostream&, const Matrix&);



Implementation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// SET OUTPUT FORMAT SETTINGS
void Matrix::setPrinter(int aColWidth, int aPrecision){
    m_print_col_width = aColWidth;
    m_print_precision = aPrecision;
}

// << OPERATOR
std::ostream& operator<< (std::ostream& out, const Matrix &rhs){
    for (auto row: rhs.m_value){
        for (auto col: row){
            out
            << std::setw(rhs.m_print_col_width)
            << std::setprecision(rhs.m_print_precision)
            << col;
        }
        out << '\n';
    }
    return out;
}
On line 7: Matrix(std::string a) : path(a) {};
Prefer to make single-argument constructors explicit:
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c46-by-default-declare-single-argument-constructors-explicit
Last edited on
Topic archived. No new replies allowed.