所以我得到了一个包含十个矩阵的文件,我想从文件中读取这些矩阵并将它们保存到向量/数组中,其中每个矩阵都存储在向量或数组中。然而,这些矩阵的格式使我很难读取数据(我不擅长从输入文件中读取)。
该文件具有以下格式。每个矩阵的元素用 "," . 每行用“;”分隔,每个矩阵用“|”分隔。例如三个2 x 2矩阵如下。
1,2;3,4|0,1;1,0|5,3;3,1|
我只想将矩阵保存到三个不同的向量中,但我不确定如何做到这一点。
我试过了
while(getline(inFile,line)){
stringstream linestream(line);
string value;
while(getline(linestream, value, ','){
//save into vector
}
}
但这显然是非常粗糙的,并且只通过逗号来分隔数据。有没有办法用多个分隔符来分隔数据?
谢谢你!
string line;
while(getline(infile, line, '|'))
{
stringstream rowstream(line);
string row;
while(getline(rowstream, row, ';'))
{
stringstream elementstream(row);
string element;
while(getline(elementstream, element, ','))
{
cout << element << endl;
}
}
}
使用上面的代码,您可以构建存储单个元素
的逻辑。
我使用这个自己的函数将字符串拆分为字符串向量:
/**
* \brief Split a string in substrings
* \param sep Symbol separating the parts
* \param str String to be splitted
* \return Vector containing the splitted parts
* \pre The separator can not be 0
* \details Example :
* \code
* std::string str = "abc.def.ghi..jkl.";
* std::vector<std::string> split_str = split('.', str); // the vector is ["abc", "def", "ghi", "", "jkl", ""]
* \endcode
*/
std::vector<std::string> split(char sep, const std::string& str);
std::vector<std::string> split(char sep, const std::string& str)
{
assert(sep != 0 && "PRE: the separator is null");
std::vector<std::string> s;
unsigned long int i = 0;
for(unsigned long int j = 0; j < str.length(); ++j)
{
if(str[j] == sep)
{
s.push_back(str.substr(i, j - i));
i = j + 1;
}
}
s.push_back(str.substr(i, str.size() - i));
return s;
}
然后,假设你有一个类矩阵,你可以做这样的事情:
std::string matrices_str;
std::ifstream matrix_file(matrix_file_name.c_str());
matrix_file >> matrices_str;
const std::vector<std::string> matrices = split('|', matrices_str);
std::vector<Matrix<double> > M(matrices.size());
for(unsigned long int i = 0; i < matrices.size(); ++i)
{
const std::string& matrix = matrices[i];
const std::vector<std::string> rows = split(';', matrix);
for(unsigned long int j = 0; j < rows.size(); ++j)
{
const std::string& row = matrix[i];
const std::vector<std::string> elements = split(',', row);
for(unsigned long int k = 0; k < elements.size(); ++k)
{
const std::string& element = elements[k];
if(j == 0 && k == 0)
M[i].resize(rows.size(), elements.size());
std::istringstream iss(element);
iss >> M[i](j,k);
}
}
}
或者,压缩代码:
std::string matrices_str;
std::ifstream matrix_file(matrix_file_name.c_str());
matrix_file >> matrices_str;
const std::vector<std::string> matrices = split('|', matrices_str);
std::vector<Matrix<double> > M(matrices.size());
for(unsigned long int i = 0; i < matrices.size(); ++i)
{
const std::vector<std::string> rows = split(';', matrices[i]);
for(unsigned long int j = 0; j < rows.size(); ++j)
{
const std::vector<std::string> elements = split(',', matrix[i]);
for(unsigned long int k = 0; k < elements.size(); ++k)
{
if(j == 0 && k == 0)
M[i].resize(rows.size(), elements[k].size());
std::istringstream iss(elements[k]);
iss >> M[i](j,k);
}
}
}
您可以使用有限状态机
概念。您需要为每个步骤定义状态。读取一个字符,然后决定它是什么(数字或分隔符)。
这是你可以做到的概念。如需更多阅读,请在Internet上查看此内容。文本解析
、有限状态机
、词法分析器
、形式语法
enum State
{
DECIMAL_NUMBER,
COMMA_D,
SEMICOLON_D,
PIPE_D,
ERROR_STATE,
};
char GetChar()
{
// implement proper reading from file
static char* input = "1,2;3,4|0,1;1,0|5,3;3,1|";
static int index = 0;
return input[index++];
}
State GetState(char c)
{
if ( isdigit(c) )
{
return DECIMAL_NUMBER;
}
else if ( c == ',' )
{
return COMMA_D;
}
else if ( c == ';' )
{
return SEMICOLON_D;
}
else if ( c == '|' )
{
return PIPE_D;
}
return ERROR_STATE;
}
int main(char* argv[], int argc)
{
char c;
while ( c = GetChar() )
{
State s = GetState(c);
switch ( c )
{
case DECIMAL_NUMBER:
// read numbers
break;
case COMMA_D:
// append into row
break;
case SEMICOLON_D:
// next row
break;
case PIPE_D:
// finish one matrix
break;
case ERROR_STATE:
// syntax error
break;
default:
break;
}
}
return 0;
}