如何正确重载流操作符?



我试图重载>>操作符,以便我可以打开ifstream文件并将其内容读入类中的数组。由于某些原因,当我做这样的事情

ifstream puzzle;
Sudoku x; //Sudoku is the name of myclass
puzzle.open("example.txt", ios::in);
puzzle >> x;    

它不会把我想要的东西转移到x对象上。运行代码后没有弹出错误,但当我查看对象数组中的内容时,它只是初始化时一个充满零的数组。这是我的代码的基本重建。

class Sudoku
{
public:
Sudoku();
~Sudoku(){}
int getValue(int row, int col){return grid[row][col];}
void setValue(int row,int col,int num) {grid[row][col]=num;}
friend ifstream& operator>>(ifstream &input, Sudoku &s);
private:
int grid[9][9];
};

ifstream& operator>>(ifstream &input, Sudoku &s)
{
int x = 0, i = 0, j = 0;
while (input >> x)
{
if (j >= 9)
{
i++;
j = 0;
}
if (i >= 9)
{
return input;
}
s.setValue(i, j, x);
j++;
}
return input;
}

如果输入文件格式正确,您的函数填充x就可以了-但是有一个很大的缺陷。在检查是否应该阅读之前,先阅读while (input >> x)。如果你已经读取了文件中的所有值,它将在输入流上设置failbit,所以如果你这样做来检查:

if(puzzle >> x) {
std::cout << "successn";
} else {
std::cout << "failuren";
}

它将打印,failure,即使所有的值都被读取-只是因为您试图读取一个值太多。

我建议将其简化为只读取恰好有多少值(9 x 9),并且,使其从读取任何istream,而不仅仅是ifstreams。

friend声明变成:

friend std::istream& operator>>(std::istream &input, Sudoku &s);

和实现:

std::istream& operator>>(std::istream &input, Sudoku &s) {
for(int i = 0; i < 9; ++i) {
for(int j = 0; j < 9; ++j) {
// There's no need to use setValue since you made it a friend
input >> s.grid[i][j];
}
}
return input;
}

检查输入文件。数字之间有空白吗?如果没有-确保它有,否则你的operator>>将无法工作。

下面是一个完整的工作示例。你会注意到一些事情。

  1. 我从不使用朋友类,没有理由这样做。
  2. 我创建了一个操作符>>函数,这样我就可以把它写出来了。
  3. 我operator<& lt;期望一个iststream而不是更具体的ifstream。该方法不应该关心它是ifstream,所以使它更通用是更好的。
  4. 我的比你的简单。

它可以编译(至少在c++ 17下)并正常运行。我不完全确定为什么你的不行。

#include <iostream>
#include <fstream>
using std::cout;
using std::endl;
using std::ifstream;
using std::istream;
class Sudoku
{
public:
Sudoku() {};
~Sudoku(){}
int getValue(int row, int col){return grid[row][col];}
void setValue(int row,int col,int num) {grid[row][col]=num;}
private:
int grid[9][9];
};
std::istream & operator>> (std::istream &input, Sudoku &s)
{
int row = 0;
int col = 0;
while (row < 9) {
int cellValue;
if (!(input >> cellValue)) {
std::cout << "Out of input." << endl;
return input;
}
s.setValue(row, col, cellValue);
if (++col >= 9) {
++row;
col = 0;
}
}
return input;
}
std::ostream & operator<< (std::ostream &oStr, Sudoku &s) {
for (int row = 0; row < 9; ++row) {
for (int col = 0; col < 9; ++col) {
if (col % 3 == 0) {
oStr << " ";
}
oStr << s.getValue(row, col);
}
oStr << endl;
}
return oStr;
}
int main(int, char **) {
std::ifstream input("sudoku.txt");
Sudoku sudoku;
input >> sudoku;
std::cout << sudoku << std::endl;
}

相关内容

  • 没有找到相关文章

最新更新