2017-11-15 32 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; 
    } 

을이 코드가 작동 : 나는 지금까지 무엇을 가지고

는 다음과 같습니다. 그러나, 내가 좋아하지 않는 세 번 파일을 열어야합니다. 이것을 회피 할 수있는 방법이 있습니까?

getRows() 및 getColumns()에서 임시 파일로 작업하는 것에 대해 생각하고 있었지만 최근에 배웠던 것처럼 이해가되지 않아 복사 스트림을 사용할 수 없습니다.

그래서 다른 방법이 있습니까? 또는 예를 들어 getline() 및 line.erase() 메서드를 피할 수 있습니까?

+1

왜 파일을 세 번 열어야합니까? – 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을 기반으로하는 경우 벡터를 한 번에 한 행씩 늘릴 수 있으므로 미리 크기를 알 필요가 없습니다.

#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 행렬에 값을 설정합니다. –