我需要在C ++上使用简单的程序,它可以从文本文件中获取两个矩阵,并且每个矩阵的行数和列数都是这样的:
这是ex的文本文件包含
3 5
1 -2 3 4 5
1 2 -3 4 5
-1 2 3 4 5
5 4
-1 2 3 4
1 -2 3 4
1 2 -3 4
1 2 3 -4
-1 -2 -3 -4
每个矩阵的第一行包含行数和列数
这是我试图做的编程
#include <cstdio>
#include <cstring>
#include <fstream>
#define Height 3
#define Width 5
// I assume that each input line in the file can contain at most width * 3 characters.
// Three extra characters for NL, CR, 0.
// Change this if you expect the file to contain longer lines.
#define BUFFER_WIDTH (Width * 3 + 3)
unsigned char Map[Height][Width];
char line[BUFFER_WIDTH];
// Remove CR, NL at the end of the line.
void clean_line(char *line)
{
int len = strlen(line);
while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r'))
{
line[len - 1] = '\0';
len--;
}
}
int main ()
{
FILE *fp = fopen("input1.txt","r");
int row = 0;
while (!feof(fp) && row < Height)
{
fgets(line, BUFFER_WIDTH, fp);
clean_line(line);
int len = strlen(line);
int rowLen = len > Width ? Width : len;
for (int col = 0; col < rowLen; col++)
{
Map[row][col] = line[col];
printf("%d ",Map[row][col]);
}
printf("\n");
row++;
}
fclose(fp);
return 0;
}
答案 0 :(得分:1)
您需要整体解析文件,然后通过某些分隔符(在这种情况下为换行符和空格)对其进行拆分。此过程称为标记化。许多库如boost或poco都支持这样的操作。
答案 1 :(得分:1)
#include <iostream>
void matUpdate(int***mat,int& row,int& col,int**matData,int& rowData,int& colData) {
*mat = matData;
row = rowData;
col = colData;
}
int read(int***mat1,int***mat2,int& row1,int& col1,int& row2,int& col2)
{
FILE* fp = fopen("mat.txt","r");
if (fp == NULL) {
return -1;
}
int row,col,matNum = 0;
while(matNum < 2) {
if (fscanf(fp,"%d %d",&row,&col) != 2 || row < 0 || col < 0) {
return -1;
}
int i,j;
int** mat = new int*[row];
for (i = 0; i < row;++i) {
mat[i] = new int[col];
}
for (i = 0;i < row;++i) {
for (j = 0;j < col;++j) {
fscanf(fp,"%d",&mat[i][j]);
}
}
if (matNum) {
matUpdate(mat2,row2,col2,mat,row,col);
}
else {
matUpdate(mat1,row1,col1,mat,row,col);
}
matNum++;
}
return fp;
}
int main()
{
int **mat1 = NULL,**mat2 = NULL;
int row1,col1,row2,col2;
FILE* fp = read(&mat1,&mat2,row1,col1,row2,col2);
if (fp != - 1) {
//work with matrics
//delete memory allocated for matrics
fclose(fp);
}
else {
//error
}
}
答案 2 :(得分:0)
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> read_matrix(istream& in)
{
int rows, cols;
in >> rows >> cols;
vector<vector<int>> matrix(rows, vector<int>(cols));
for (auto& row : matrix)
for (auto& cell : row)
in >> cell;
return matrix;
}
int main()
{
fstream in("input.txt");
vector<vector<int>> mat1 = read_matrix(in);
vector<vector<int>> mat2 = read_matrix(in);
}
答案 3 :(得分:0)
我最近编写了一个相当简单的CSV阅读器类,这可以帮助你做很多事情。我还在堆栈交换代码审查posted this code。这还包括对代码的一些评论。我使用boost::MultiArray
将结果存储在2d数组中,并使用boost::split
将文件中的文本拆分为数字。
以下是代码:
头文件:
#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>
class BadConversion : public std::runtime_error {
public:
BadConversion(std::string const& s)
: std::runtime_error(s)
{ }
};
class BadIndex : public std::runtime_error {
public:
BadIndex(std::string const& s)
: std::runtime_error(s)
{ }
};
inline double convertToDouble(std::string const& s)
{
std::istringstream i(s);
double x;
if (!(i >> x))
throw BadConversion("convertToDouble(\"" + s + "\")");
return x;
}
和c ++代码,包括一些示例使用:
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <boost/algorithm/string.hpp>
#include <boost/multi_array.hpp>
#include "csv-test.h"
#include <cassert>
template <class T> class csv_reader {
boost::multi_array<T, 2> content2d ;
std::vector<std::string> split_line ;
std::string line;
std::string sep ;
int ncol ;
int nrow ;
public :
csv_reader(std::string, std::string) ; // constructor
~csv_reader(); // desctructor
void cout_content() ; // print the contents
T operator() (unsigned row, unsigned column) ;
} ;
// Constructor
template <class T> csv_reader<T>::csv_reader(std::string path, std::string sep = ",")
{
// Initializing variables
ncol = 0 ; // Initialize the number of colums to 0
nrow = 1 ; // Initialize the number of rows to 1
content2d = boost::multi_array<T, 2> (boost::extents[0][0]) ;
std::ifstream data(path.c_str()) ;
// read the csv data
while(getline(data, line))
{
boost::split(split_line, line, boost::is_any_of(sep) ) ;
if(ncol == 0)
{
ncol = split_line.size() ;
}
else assert(ncol == split_line.size()) ;
content2d.resize(boost::extents[nrow][ncol]) ;
for(int i = 0; i < split_line.size(); i++)
{
content2d[nrow - 1][i] = convertToDouble(split_line[i]) ;
}
nrow++ ;
}
}
// Destructor
template <class T> csv_reader<T>::~csv_reader() { }
template <class T> void csv_reader<T>::cout_content()
{
for(int row = 0; row < (nrow - 1); row++)
{
for(int col = 0; col < ncol ; col++)
{
std::cout << content2d[row][col] << " ";
}
std::cout << "\n" ;
}
}
// Allow access to the contents
template <class T> T csv_reader<T>::operator() (unsigned row, unsigned column)
{
if (row >= nrow || column >= ncol)
throw BadIndex("boost::MultiArray subscript out of bounds");
return(content2d[row][column]) ;
}
int main()
{
// An integer csv reader
csv_reader<int> csv_obj_int("test.csv") ;
csv_obj_int.cout_content() ;
// A double csv reader
csv_reader<double> csv_obj_double("test.csv") ;
csv_obj_double.cout_content() ;
// It also supports direct access to the content using operator()
std::cout << csv_obj_double(1,1) << "\n" ;
std::cout << csv_obj_double(1,1) * 5 << "\n" ;
// This statement fails with a subscript out of bounds error
// std::cout << csv_obj_double(10,10) * 5 << "\n" ;
// Testing a different seperator
csv_reader<double> csv_obj_double_sep2("test_semicol.csv", ";") ;
csv_obj_double_sep2.cout_content() ;
}