0

テキストファイルから2つの行列を取り、次のようにそれぞれの行と列の数を取ることができる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;
}
4

4 に答える 4

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
    }

}
于 2012-04-09T11:26:40.423 に答える
1

ファイル全体を解析してから、区切り文字 (この場合は改行と空白) で分割する必要があります。このプロセスはトークン化と呼ばれます。boost や poco などの多くのライブラリは、このような操作をサポートしています。

クラス StringTokenizer

ブースト::スプリット

于 2012-04-09T10:44:44.123 に答える
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);
}
于 2012-04-09T11:32:41.940 に答える
0

私は最近、かなり単純な CSV リーダー クラスを作成しました。これは、探している多くのことを行います。このコードは、stack exchange Code Reviewにも投稿しました。これには、コードに関するいくつかのコメントも含まれます。私boost::MultiArrayは結果を 2 次元配列に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() ;
}
于 2012-04-09T11:32:43.477 に答える