我无法读取用户的输入并将其转换为矩阵进行计算。例如,对于input = {1 2 3 / 4 5 6}
,程序应该以
1 2 3
4 5 6
有3列和2行。到目前为止我得到的似乎不起作用:
input.replace(input.begin(), input.end(), '/', ' ');
stringstream ss(input);
string token;
while (getline(ss, token, ' '))
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
int tok = atoi(token.c_str());
(*matrix).setElement(i, j, tok);
}
}
}
所以我要做的是将输入分解为令牌并使用setElement函数将它们存储到矩阵中,该函数接受用户想要存储的行数,列数和变量数。这段代码有什么问题,tok
的变量似乎没有改变并一直停留在0
。假设知道行和col。
非常感谢您的帮助。
答案 0 :(得分:1)
虽然有很多简单的方法可以解决具体问题(其他答案有各种好的建议),但我试着对“格式化输入”问题给出一个更一般的看法。
这里存在三种问题:
这三件事并不是完全独立的,最后需要知道如何存储元素(你如何调整矩阵的大小?)
最后还有第4个问题(其他3个问题就是其他问题):如果输入“错误”该怎么办。
这类问题通常以两种相反的方式提供:
第2点需要良好的字符串操作,但还需要能够知道输入的长度(如果其中一个分隔空间是一个新行会发生什么?这个想法是通过{{1}得到的所有内容在这些情况下失败)
第1点需要一个getline
类,它能够在您阅读时增长,或者需要一个临时动态结构(如和Matrix
容器),您可以将其放入适当的位置,然后再将其发送到相应的的地方。
由于我不知道你的矩阵是如何工作的,让我保留一个临时向量和计数器来存储行。
std
现在您可以将矩阵读作
#include <vector>
#include <iostream>
#include <cassert>
class readmatrix
{
std::vector<int> data; //storage
size_t rows, cols; //the counted rows and columns
size_t col; //the counting cols in a current row
Matrix& mtx; //refer to the matrix that has to be read
public:
// just keep the reference to the destination
readmatrix(Matrix& m) :data(), rows(), cols(), cols(), mtx(m)
{}
// make this class a istream-->istream functor and let it be usable as a stream
// manipulator: input >> readmatrix(yourmatrix)
std::istream& operator()(std::istream& s)
{
if(s) //if we can read
{
char c=0:
s >> c; //trim spaces and get a char.
if(c!='{') //not an open brace
{ s.setstate(s.failbit); return s; } //report the format failure
while(s) //loop on rows (will break when the '}' will be found)
{
col=0;
while(s) //loop on cols (will break when the '/' or '}' will be found)
{
c=0; s >> c;
if(c=='/' || c=='}') //row finished?
{
if(!cols) cols=col; //got first row length
else if(cols != col) //it appears rows have different length
{ s.setstate(s.failbit); return s; } //report the format failure
if(c!='/') s.unget(); //push the char back for later
break; //row finished
}
s.unget(); //pushthe "not /" char back
int x; s >> x; //get an integer
if(!s) return s; //failed to read an integer!
++col; data.push_back(x); //save the read data
}
++rows; //got an entire row
c=0; s >> c;
if(c == '}') break; //finished the rows
else s.unget(); //push back the char: next row begin
}
}
//now, if read was successful,
// we can dispatch the data into the final destination
if(s)
{
mtx.setsize(rows,cols); // I assume you can set the matrix size this way
auto it = data.begin(); //will scan the inner vector
for(size_t r=0; r<rows; ++r) for(size_t c=0; c<cols; ++c, ++it)
mtx(r,c) = *it; //place the data
assert(it == data.end()); //this must be true if counting have gone right
}
return s;
}
};
此时您会注意到代码中存在某些重复出现的模式:这在单遍解析中很常见,并且这些模式可以分组以形成子解析器。如果你这样做,你实际上会重写input >> readmatrix(matrix);
。
当然可以根据矩阵的工作方式(固定大小?)或者行大小不匹配(部分列填充??)来进行一些调整
您甚至可以添加格式化的输入操作符,如
boost::spirit
这样你就可以做到
std::istream& operator>>(std::istream& s, Matrix& m)
{ return s >> readmatrix(m); }
答案 1 :(得分:0)
您正在尝试对输入中读取的每个字符的矩阵的每个单元格进行操作! 你必须为每个单元格取一个char,而不是多个。
可以使用以下函数在标记中拆分字符串。 请不要担心以下代码无法运行,这是由于缺少矩阵类。
尝试以下方法:
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
using namespace std;
void split(const string& str, char delimiter, vector<string>& result) {
string::size_type i = 0;
string::size_type delimOcc = str.find(delimiter);
while (delimOcc != string::npos) {
result.push_back(str.substr(i, delimOcc-i));
i = ++delimOcc;
delimOcc = str.find(delimiter, delimOcc);
if (delimOcc == string::npos) {
result.push_back(str.substr(i, str.length()));
}
}
}
int main()
{
std::string input = "1 2 3 / 4 5 6";
vector<string> rows;
split(input, '/', rows);
for(int i = 0; i < rows.size(); i++) {
vector<string> cols;
split(rows[i], ' ', cols);
for(int j = 0; j < cols.size(); j++) {
if(cols[j][0] != '\0'){
int tok = stoi(cols[j]);
(*matrix).setElement(i, j, tok);
cout << tok << " - " << i << " - " << j << endl;
}
else {
if(j == 0) j--;
}
}
}
return 0;
}
答案 2 :(得分:0)
如果你知道正手矩阵的大小,你实际上不需要getline,你应该用int读取int。 (未经测试的代码)
input.replace(input.begin(), input.end(), '/', '\n');
stringstream ss(input);
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
int tok;
ss >> tok;
(*matrix).setElement(i, j, tok);
}
}