C++ istream 运算符 >>
c++ istream operator >>
我的操作符有问题>>
istream& operator>> (istream& is, Matrix& M) {
char first;
is>>first;
for(int i = 0;i<M.rows();i++) {
for(int j = 0;j<M.cols();j++) {
is>>M[i][j];
cout<<M[i][j];
}
is>>first;
}
return is;
}
我想要istream操作符的大小,因为我想改变for循环,这样它们就不依赖于发送进来的矩阵,也就是说,如果你发送一个大小为1的矩阵和流[1 2 3 4; 4 5 6 7; 1 2 3 4]
,那么应该构造一个大小为(3*4)的新矩阵。这样我就可以使用赋值运算符将其赋值给矩阵m。
也就是说,流的形式是"[ 1 2 3; 2 3 4; 4 5 6]"
和;表示新行。我想知道有多少行和颜色
你可以像这样得到所有的行:
vector<string> rows;
string line;
is.ignore(INT_MAX, '['); // ignores all characters until it passes a [
while (std::getline(is, line, ';'))
rows.push_back(line); // put each row in rows
rows.back().erase(rows.back().find(']')); // erase the ending ]
现在你有rows
中的每一行字符串,然后
for (size_t i = 0; i < rows.size(); ++i) {
vector<int> items;
istringstream strstm(rows[i]);
std::copy(istream_iterator<int>(strstm), istream_iterator<int>(), back_inserter(items));
// now items is full of the entries, resize the matrix to hold items.size()
// many items and insert each one into it, or whatever
}
首先,当然,您需要指定比您更严格的东西有。您应该如何处理"[ 11 12 13; 21 22; 31 32
33 ]"
之类的东西,例如:为缺失的值或集合插入0.0
failbit
?
除此之外,使用std::vector
收集输入将使事情变成a更容易一些。例如:
template< typename T >
char getRow( std::istream& source, std::vector<T>& dest )
{
dest.clear();
char separator;
source >> separator;
while ( source && separator != ';' && separator != ']' ) {
source.unget();
T tmp;
source >> tmp;
if ( source ) {
dest.push_back( tmp );
source >> separator;
}
}
if ( source && dest.empty() ) {
dest.setstate( std::ios_base::failbit );
}
return source ? separator : ' ';
}
template< typename T >
char getFirstRow( std::istream& source,
std::vector<std::vector<T> >& dest )
{
dest.clear();
std::vector<T> row;
char separator = getRow( source, row );
if ( source ) {
if ( row.empty() ) {
dest.setstate( std::ios_base::failbit );
} else {
dest.push_back( row );
}
}
return source ? separator : ' ';
}
template< typename T >
char getFollowingRow( std::istream& source,
std::vector<std::vector<T> >& dest )
{
std::vector<T> row;
char separator = getRow( source, row );
if ( source ) {
if ( row.size() != dest.front().size() ) {
dest.setstate( std::ios_base::failbit ) ;
} else {
dest.push_back( row );
}
}
return source ? separator : ' ';
}
template< typename T >
std::istream&
operator>>( std::istream& source, Matrix<T>& dest )
{
char separator;
source >> separator;
if ( separator != '[' ) {
source.setstate( std::ios_base::failbit );
} else {
std::vector<std::vector<T> > results;
separator = getFirstRow( source, results );
while ( separator == ';' ) {
separator = getFollowingRow( source, results );
}
if ( separator != ']' ) {
source.setstate( std::ios_base::failbit );
}
if ( source ) {
dest.assign( results );
}
}
return source;
}
当然,这意味着Matrix<T>::assign
函数必须能够设置尺寸。为了可用,Matrix<T>
需要一个默认值构造函数,它可能将实际构造"推迟"到Matrix<T>::assign
.
也:我们在上面的可能性有限用于在iostreams中报告错误。特别是,我们真的很想区分像"[11 12 13; 21"
这样的输入和什么都没有(真正的结束)文件条件)。但是我们试图读取"21"
之后的分隔符会设置eofbit
,我们对此无能为力。(实际上,we 可以创建一个新的状态词,使用std::ios_base::xalloc()
,当且仅当在开始时读取'['
失败时设置它eofbit
集。但这需要一种非常不标准的检查方式对于客户端代码中的错误,这将反过来创建一个无尽的流)
最后,两个元注释:如果这看起来很复杂…它是。输入几乎总是很复杂,因为有各种各样的错误你必须检查的条件。第二,注意函数的使用保持每个单独的操作(某种程度上)简单。这是经常发生的初学者不像这样把事情分解是错误的几乎总是糟糕的编程,例如,在函数,除了将数学算法应用于Matrix
。在这种情况下,解析不是数学算法,并且您希望将每行的处理与总体处理分开;在这种情况下,分离第一行的处理也很有用与其他的不同,因为错误情况是不同的。(第一行可以有任何大于0的长度,后面的行必须有相同的长度)
问题是流提取操作符需要一个已经构造的对象,它可以修改这个对象。你必须调整你的矩阵类,以便它可以动态调整大小。
不可能确定" istream操作符的大小",因为它是流,当您读取第一个矩阵元素时,没有人可以保证最后一个元素已经存在。您应该首先读取整个字符串,然后解析它并提取有关输入矩阵大小的信息。之后,您可以通过stringstream
向它提供这个字符串来使用您的代码。当然,你必须能够动态地改变矩阵的大小。
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 通过继承类使用来自不同命名空间的运算符
- C++Cast运算符过载
- 如何使用AngelScript注册SFML Vector2运算符
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 布尔比较运算符是如何在C++中工作的
- 重载运算符new[]的行为取决于析构函数
- 是否需要使用 - &gt;运算符在C 中调用成员函数时