读取文件到 istream 替换 class 变量
Read file to istream replacing class variables
我了解如何实现重载的 ostream 运算符,但我对重载的 istream 运算符有点困惑。所有在线示例仅显示了一个简短的演示(即 is >> val; ),这对我 class 变量和方法的上下文没有帮助。总的来说,我试图读入一个文件并将指针内容替换为文件内容。我已经有一个工厂方法和读取方法可以执行此操作,但我正在尝试重载我的 istream 运算符以执行相同的操作。 但是,尽管指针内容被替换了,我仍然收到下面的 cerr 消息。我是否支持os在我的 >> 函数中向 ifs 传递一些东西?
这是我的主要内容
int main() {
// factory method instantiates all class variables
Base *aa = Base::create(file); // it works
ifstream in(file2);
if((in >> *aa).fail()) // Read file contents
cerr << "Read failed" << '\n';
cout << *aa; // prints vector contents
}
版画
// file // file2 cout << *aa SupposedToBe
555 111 Read Failed 111
555 222 111 222
555 333 222 333
333
到目前为止我有什么 (.cpp)
istream &operator>>(istream &ifs, Base &val) {
string line;
getline(ifs, line); // type of file
if(line == "type1")
val.filetype = "type1";
if(line == "type2")
val.filetype = "type2";
val.vec.clear(); // clear old vector
vector<int> inner; // inner vec to push onto main vec
// read remaining contents
while(getline(ifs, line)) {
for(size_t i = 0; i < line.length(); i++)
inner.push_back(line[i]);
val.vec.push_back(inner);
inner.clear();
}
val.height = val.vec.size();
val.width = val.vec[0].size();
val.max = val.vec[height-1][width-1];
return ifs;
}
我重载的 ostream 函数看起来与上面显示的有很大不同(即很多 os << 值)。但是,每当我执行 ifs >> value 时,我都会遇到各种编译器错误(即我尝试只执行 ifs >> val.image; ifs >> val.height; 等等,但我得到的只是编译器错误).我支持os 传递给 istream(在上面的函数中)的内容是什么,所以不会显示上面的错误(在 main 之下)。
.h文件供参考
class Base
{
protected:
std::vector<std::vector<int> > vec;
std::string filetype;
int width, height, max;
Base() = default;
Base &operator=(const Base &) = default;
public:
static Base* create(std::string filename);
virtual ~Base();
// read by derived class
virtual void read(std::string filename) = 0;
friend std::istream &operator>>(std::istream &, Base &);
friend std::ostream &operator<<(std::ostream &, const Image &);
};
使用
if((in >> *aa).fail()) // Read file contents
cerr << "Read failed" << '\n';
是个问题。您实施 operator>>(std::istream &, Base &)
的方式每次都注定会失败。
函数中有一个循环
while(getline(ifs, line)) {
...
}
只有当没有任何内容可从文件中读取或读取文件内容时出现错误时,该循环才会中断。当该循环退出时,ifs.fail()
将始终为真。
您应该将 if
语句替换为:
in >> *aa;
如果您需要进行任何错误检查并打印适当的错误消息,则必须在 operator>>(std::istream &, Base &)
内完成。
更新,回应 OP 的评论
确保 istream
不会达到 ifs.fail()
始终 true
的地步的一种方法是提前知道预期的结果。
如果文件中预期的行数是第一个输入,那么,可以从函数中读取所有数据和return使得ifs.fail()
是false
.
示例输入:
type1
3
111
222
333
那么,oprator>>
函数可以定义为:
std::stream& operator>>(std::istream& ifs, Base& val)
{
std::string line;
if ( !getline(ifs, line) ) // type of file
{
// Problem reading. No point trying to read more.
return ifs;
}
if(line == "type1")
val.filetype = "type1";
if(line == "type2")
val.filetype = "type2";
// read remaining contents
int numLines = 0;
if ( !(ifs >> numLines) )
{
// Problem reading. No point trying to read more.
return ifs;
}
val.vec.clear(); // clear old vector
vector<int> inner; // inner vec to push onto main vec
for ( int n = 0; n < numLines; ++n )
{
if ( !getline(ifs, line))
{
// Problem reading. No point trying to read more.
return ifs;
}
for(size_t i = 0; i < line.length(); i++)
{
inner.push_back(line[i]);
}
val.vec.push_back(inner);
inner.clear();
}
val.height = val.vec.size();
val.width = val.vec[0].size();
val.max = val.vec[height-1][width-1];
return ifs;
}
我了解如何实现重载的 ostream 运算符,但我对重载的 istream 运算符有点困惑。所有在线示例仅显示了一个简短的演示(即 is >> val; ),这对我 class 变量和方法的上下文没有帮助。总的来说,我试图读入一个文件并将指针内容替换为文件内容。我已经有一个工厂方法和读取方法可以执行此操作,但我正在尝试重载我的 istream 运算符以执行相同的操作。 但是,尽管指针内容被替换了,我仍然收到下面的 cerr 消息。我是否支持os在我的 >> 函数中向 ifs 传递一些东西?
这是我的主要内容
int main() {
// factory method instantiates all class variables
Base *aa = Base::create(file); // it works
ifstream in(file2);
if((in >> *aa).fail()) // Read file contents
cerr << "Read failed" << '\n';
cout << *aa; // prints vector contents
}
版画
// file // file2 cout << *aa SupposedToBe
555 111 Read Failed 111
555 222 111 222
555 333 222 333
333
到目前为止我有什么 (.cpp)
istream &operator>>(istream &ifs, Base &val) {
string line;
getline(ifs, line); // type of file
if(line == "type1")
val.filetype = "type1";
if(line == "type2")
val.filetype = "type2";
val.vec.clear(); // clear old vector
vector<int> inner; // inner vec to push onto main vec
// read remaining contents
while(getline(ifs, line)) {
for(size_t i = 0; i < line.length(); i++)
inner.push_back(line[i]);
val.vec.push_back(inner);
inner.clear();
}
val.height = val.vec.size();
val.width = val.vec[0].size();
val.max = val.vec[height-1][width-1];
return ifs;
}
我重载的 ostream 函数看起来与上面显示的有很大不同(即很多 os << 值)。但是,每当我执行 ifs >> value 时,我都会遇到各种编译器错误(即我尝试只执行 ifs >> val.image; ifs >> val.height; 等等,但我得到的只是编译器错误).我支持os 传递给 istream(在上面的函数中)的内容是什么,所以不会显示上面的错误(在 main 之下)。
.h文件供参考
class Base
{
protected:
std::vector<std::vector<int> > vec;
std::string filetype;
int width, height, max;
Base() = default;
Base &operator=(const Base &) = default;
public:
static Base* create(std::string filename);
virtual ~Base();
// read by derived class
virtual void read(std::string filename) = 0;
friend std::istream &operator>>(std::istream &, Base &);
friend std::ostream &operator<<(std::ostream &, const Image &);
};
使用
if((in >> *aa).fail()) // Read file contents
cerr << "Read failed" << '\n';
是个问题。您实施 operator>>(std::istream &, Base &)
的方式每次都注定会失败。
函数中有一个循环
while(getline(ifs, line)) {
...
}
只有当没有任何内容可从文件中读取或读取文件内容时出现错误时,该循环才会中断。当该循环退出时,ifs.fail()
将始终为真。
您应该将 if
语句替换为:
in >> *aa;
如果您需要进行任何错误检查并打印适当的错误消息,则必须在 operator>>(std::istream &, Base &)
内完成。
更新,回应 OP 的评论
确保 istream
不会达到 ifs.fail()
始终 true
的地步的一种方法是提前知道预期的结果。
如果文件中预期的行数是第一个输入,那么,可以从函数中读取所有数据和return使得ifs.fail()
是false
.
示例输入:
type1
3
111
222
333
那么,oprator>>
函数可以定义为:
std::stream& operator>>(std::istream& ifs, Base& val)
{
std::string line;
if ( !getline(ifs, line) ) // type of file
{
// Problem reading. No point trying to read more.
return ifs;
}
if(line == "type1")
val.filetype = "type1";
if(line == "type2")
val.filetype = "type2";
// read remaining contents
int numLines = 0;
if ( !(ifs >> numLines) )
{
// Problem reading. No point trying to read more.
return ifs;
}
val.vec.clear(); // clear old vector
vector<int> inner; // inner vec to push onto main vec
for ( int n = 0; n < numLines; ++n )
{
if ( !getline(ifs, line))
{
// Problem reading. No point trying to read more.
return ifs;
}
for(size_t i = 0; i < line.length(); i++)
{
inner.push_back(line[i]);
}
val.vec.push_back(inner);
inner.clear();
}
val.height = val.vec.size();
val.width = val.vec[0].size();
val.max = val.vec[height-1][width-1];
return ifs;
}