我的运营商有一些问题>>
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循环,以便它们不依赖于发送的Matrix,即你是否发送大小为1的矩阵和流{{ 1}}然后应该构造一个大小为(3 * 4)的新矩阵。这样我就可以使用赋值运算符将其赋值给矩阵M.
换句话说,流的格式为[1 2 3 4; 4 5 6 7; 1 2 3 4]
和;意味着新的一行。
我想知道有多少行和列。
答案 0 :(得分:2)
你可以得到这样的所有行:
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
}
答案 1 :(得分:1)
首先,当然,您需要指定比您更严格的事情
有。您应该对"[ 11 12 13; 21 22; 31 32
33 ]"
之类的事情做些什么,例如:为缺失值插入0.0
或设置
failbit
?
除此之外,使用std::vector
收集输入将使事情成为现实
有点容易。如下所示:
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 : '\0';
}
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 : '\0';
}
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 : '\0';
}
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>
需要默认值
构造函数,可能&#34;推迟&#34;实际建设,直到
Matrix<T>::assign
。
另外:由于有限的可能性,我们在上述方面有所限制
用于iostreams中的错误报告。特别是,我们真的很喜欢
区分像"[11 12 13; 21"
这样的输入和没有(真正的结束)
文件条件)。但我们尝试在"21"
之后读取分隔符
将设置eofbit
,我们无能为力。 (其实,
我们可以使用std::ios_base::xalloc()
创建新的状态字,
当且仅当在开始时读取'['
失败时才设置它
{{1套。但这需要一种非常不标准的检查方式
对于客户端代码中的错误,这反过来会产生无穷无尽的流
维修问题。)
最后,两个元评论:如果这看起来很复杂......那就是。输入
几乎总是很复杂,因为所有的各种错误
你必须检查的条件。第二,注意函数的使用
保持每个单独的操作(某种程度)简单。这是一个常见的
初学者的错误就是不要像这样把事情搞得一团糟
几乎总是糟糕的编程,例如,在a中有一个嵌套循环
函数,除了将数学算法应用于类似的东西
eofbit
。在这种情况下,解析不是数学算法,而且
你想把每一行的处理与整体处理分开;
在这种情况下,它对分离第一行的处理也很有用
来自其他人,因为错误案例不同。 (第一排
可以具有大于0的任何长度,以后的行必须具有相同的长度
如前一行。)
答案 2 :(得分:0)
问题是流提取操作符需要一个可以修改的已构造对象。您必须调整矩阵类,以便可以动态调整其大小。
答案 3 :(得分:0)
无法确定“istream运算符的大小”,因为它确实是流,当你读取第一个矩阵元素时,没有人能保证最后一个元素已经存在。您应该首先读取整个字符串,然后解析它并提取有关输入矩阵大小的信息。之后,您可以通过stringstream
向其提供此字符串来使用您的代码。当然,您必须能够动态更改矩阵的大小。