2017-11-15 15 views
0

私はcsvファイルからデータを抽出したいが、まずテーブルの行数と列数を取得する必要がある。ifstreamの削除コピーコンストラクタの代替

私がこれまで持っていることは以下の通りです:

 std::ifstream myfile(filename); // filename is a string and passed in by the constructor 
     if (myfile.is_open()) 
     { 
      // First step: Get number of rows and columns of the matrix to initialize it. 
      // We have to close and re-open the file each time we want to work with it. 
      int rows = getRows(myfile); 
      std::ifstream myfile1(filename); 
      int columns = getColumns(myfile1); 

      if (rows == columns) // Matrix has to be quadratic. 
      { 
       std::ifstream myfile2(filename); 
       abwicklungsdreieck.set_Matrix(QuantLib::Matrix(rows, columns, 0)); // abwicklungsdreieck is initialised before 
       //... 
      } 
      else 
      { 
       std::cout << "\nNumber of rows has to equal number of columns."; 
      } 
     } 
    // [...] 
    int getRows(std::ifstream &myfile) 
    { 
     std::string line; 
     int rows = 0; 

     while (std::getline(myfile, line)) // While-loop simply counts rows. 
     { 
      rows++; 
     } 
     myfile.close(); 
     return rows - 1; 
    } 

    int getColumns(std::ifstream &myfile) 
    { 
     std::string line; 
     char delimiter = ';'; 
     size_t pos = 0; 
     int columns = 0; 

     while (std::getline(myfile, line) && columns == 0) // Consider first line in the .csv file. 
     { 
      line = line + ";"; 
      while ((pos = line.find(delimiter)) != std::string::npos) // Counts columns. 
      { 
       line.erase(0, pos + 1); 
       columns++; 
      } 
     } 
     myfile.close(); 
     return columns - 1; 
    } 

このコードが機能しています。しかし、私は好きではない3回ファイルを開く必要があります。これを避ける方法はありますか?

私はGETROWS()とのgetColumnsで一時ファイルの操作について考えていた()が、コピーは、私が最近学んだとして、それは意味がありませんので、可能ではありませんストリーム。

他の方法がありますか?または、例えばgetline()メソッドとline.erase()メソッドを回避できますか?

+1

なぜ3回ファイルを開く必要があると思いますか? – user463035818

+1

はあなたの誤解の原因かもしれません。ストリームをコピーすることはできませんが、希望通りに参照を渡すことができます。一度それを開き、それを回し、いくつかのものをして、一度閉じる。 – user463035818

+0

はい、どうすればよいですか? getLine(&myfile)は機能しません。 –

答えて

0

あなたは、行毎にファイルを読み込むストリームにそれぞれの行を変換し、ストリーム上の列読むことができます:

std::ifstream myfile(filename); 
if(!myfile) return 0; 

std::string line; 
while(std::getline(myfile, line)) 
{ 
    std::stringstream ss(line); 
    std::string column; 
    while(std::getline(ss, column, ';')) 
    { 
     cout << column; 
    } 
    cout << "\n"; 
} 

getline(myfile, line)lineへの各行をコピーします。

ストリームをssストリームに変換します。

getline(ss, column, ';')は、列に改行されます。整数にして、文字列を変換する

使用std::stoi

行列がstd::vectorに基づいている場合は、ベクトルを1行ずつ増やすことができます。したがって、事前にサイズを知る必要はありません。

#include <iostream> 
#include <fstream> 
#include <string> 
#include <sstream> 
#include <vector> 

void readfile(const std::string &filename) 
{ 
    std::vector<std::vector<int>> matrix; 
    std::ifstream myfile(filename); 
    if(!myfile) return; 
    std::string buf; 
    while(std::getline(myfile, buf)) 
    { 
     int maxrow = matrix.size(); 
     std::stringstream ss(buf); 
     matrix.resize(maxrow + 1); 
     cout << "break in to columns:" << buf << "\n"; 
     while(std::getline(ss, buf, ';')) 
     { 
      try { 
       int num = std::stoi(buf); 
       matrix[maxrow].push_back(num); 
      } 
      catch(...) { } 
     } 
    } 

    for(auto &row : matrix) { 
     for(auto col : row) 
      cout << col << "|"; 
     cout << "\n"; 
    } 
} 
+0

あなたの答えをありがとう。私はベクトルを使って行列を作ることはこれをより簡単にすることを知っていますが、私はさらなるコードでそれのいくつかの関数が必要なので、QuantLib :: Matrixを使いたいと思います。したがって、行と列の数を事前に知る必要があります。 setMatrixの後に関数readFile(abwicklungsdreieck、myfile2)が呼び出され、ファイルを読み込み、その値をabwicklungsdreieckの行列に設定します。 –

関連する問題