C ++阅读大文件有几个部分

时间:2017-10-05 11:52:32

标签: c++ file

我正在尝试用C ++编写一个简单的程序,它给出了一个大的数据文件,分为几个组X,Y,Z,有一个Header,其中写有数据大小的int数字跟随...此数字前面有一个字符串“I =”,你可以在这里查看文件http://dpaste.com/19HQY58

我已经编写了一个能够很好地读取第一部分的代码..但是对于其他部分,代码无法读取...这里的代码

# include <iostream>
# include <fstream>
# include <iomanip>
# include <string>
# include <sstream>
# include <cstdlib>
# include <cmath>
# include <vector>
# include <exception>
# include <algorithm>
# include <cstring>

//----------------------------------------------------------------------------------------

using namespace std;

//--- Function prototipes 


void readData(vector<vector<vector<double>>>*, string& , int&);


//---

int main(int args, char* argv[]){

  string time,root ;    
  string filename = "stangle.000000000.dat" 
  int N;    


  vector<vector<vector<double>>>* ptrData ;

  ptrData = new vector<vector<vector<double>>>(10); 

  readData(ptrData, filename, N);


  return 0;
}


//---
//

void readData( vector<vector<vector<double>>>* data,  string& file, int& size){
      unsigned int header = 3;
      string tmp, row ;

      ifstream inputFile;

      cout << file << endl;
      try
      {
            inputFile.open(file, ios::in);
      }
      catch(...) 
      {
            cerr << "Error occurred opening file " << file << " program terminate!" << endl;
            exit(1);
      }

      int indx=0;

    int k=0;

    while(getline(inputFile,row) && (k <= 1)){
     if(k==0)
      while( k++ <= header-1 && getline(inputFile,row)){ 
            istringstream elem(row);
            if(k == header ){
                  while(elem >> tmp){
                             if(strcmp(tmp.c_str(),"I=" )== 0){
                               elem >> tmp ; 
                               size = atoi(tmp.c_str());
                             }
                  }
           }
     }
     else
     {
       int w = 0 ;
       while( w++ <= header-1 && getline(inputFile,row)){ 
            istringstream elem(row);
            if(w == header-1 ){
                  while(elem >> tmp){
                             if(strcmp(tmp.c_str(),"I=" )== 0){
                               elem >> tmp ; 
                               size = atoi(tmp.c_str());
                             }
                  }
           }
       }
      }

      cout << "size = " << size << endl;

      k=0;
      data->resize(size*3) ;
      data->at(k).resize(size*3) ;


      for(int i=0; i<size; i++)                // resize vector ! 
                  data->at(k)[i].resize(3) ;

      int j=0;
      while(getline(inputFile,row) && j < size){
            istringstream elem(row);
            for(int i=0; i < 3; i++)
                  elem >> data->at(k)[j].at(i); 
            elem >> tmp ;                    // 4th columns to skip
            j++;
      }


      k++ ;
   }   
}
有人可以帮帮我吗?谢谢

这里是样本的例子

VARIABLES= "X","Y","Z","T" 


ZONE I=    10  F=POINT  T="time=      0.0000000000 " 
  0.386493318E-01  0.128555549E-01  0.340086408E-01  0.312500005E-02
  0.383133255E-01  0.138539430E-01  0.340525173E-01  0.312500005E-02
  0.382215269E-01  0.148848109E-01  0.340615511E-01  0.312500005E-02
  0.377206728E-01  0.157320835E-01  0.342985764E-01  0.312500005E-02
  0.370856710E-01  0.163890962E-01  0.346758589E-01  0.312500005E-02
  0.365753844E-01  0.170070678E-01  0.349843502E-01  0.312500005E-02
  0.362384841E-01  0.179224834E-01  0.353175104E-01  0.312500005E-02
  0.362287983E-01  0.188916922E-01  0.356959850E-01  0.312500005E-02
  0.361620262E-01  0.199434906E-01  0.359359272E-01  0.312500005E-02
  0.361897759E-01  0.210271589E-01  0.360902399E-01  0.312500005E-02


ZONE I=     6  F=POINT  T="time=      0.0000000000 " 
  0.435949154E-01  0.254055243E-01 -0.491932891E-01  0.312500005E-02
  0.434608348E-01  0.254306290E-01 -0.482175574E-01  0.312500005E-02
  0.432049297E-01  0.259031206E-01 -0.474165194E-01  0.312500005E-02
  0.427575074E-01  0.264129750E-01 -0.467625186E-01  0.312500005E-02
  0.420416631E-01  0.268291328E-01 -0.463280752E-01  0.312500005E-02
  0.411394201E-01  0.266988464E-01 -0.461011454E-01  0.312500005E-02




ZONE I=     4  F=POINT  T="time=      0.0000000000 " 
  0.435949154E-01  0.254055243E-01 -0.491932891E-01  0.312500005E-02
  0.434608348E-01  0.254306290E-01 -0.482175574E-01  0.312500005E-02
  0.432049297E-01  0.259031206E-01 -0.474165194E-01  0.312500005E-02
  0.427575074E-01  0.264129750E-01 -0.467625186E-01  0.312500005E-02`

1 个答案:

答案 0 :(得分:1)

我建议重新设计你的程序。

您的输入文件包含记录块。所以,这样设计。

struct Record
{
  double m_values[4]; // These could be itemized if you know their purpose
};

struct Block
{
  std::string m_f;
  double      m_time;
  std::vector<Record> m_records;
};

下一步是在每个类中重载operator>>以读入数据成员。

struct Record
{
  //...
  friend std::istream& operator>>(std::istream& input, Record& r);
};

std::istream& operator>>(std::istream& input, Record& r)
{
  input >> r.m_values[0];
  input >> r.m_values[1];
  input >> r.m_values[2];
  input >> r.m_values[3];
  return input;
}

struct Block
{
  //...
  friend std::istream& operator>>(std::istream& input, Block& b);
};

std::istream& operator>>(std::istream& input, Block& b)
{
  std::string text;
  while (std::getline(input, text))
  {
    if (text.empty()) continue;
    static const char zone_key_text[] = "ZONE I=";
    std::string::size_type position = text.find(zone_key_text);
    if (position != 0) continue;
    std::istringstream text_stream(text.substr(sizeof(zone_key_text) - 1));
    int record_quantity = 0;
    text_stream >> record_quantity;
    // Parse remaining fields
    Record r;
    for (int i = 0; i < quantity; ++i)
    {
      input >> r;
      m_records.push_back(r);
    }
    //...
}

ZONE I=包含记录数。记录数量各不相同,这是使用std::vector记录的良好指标。

然后读取文件:

std::string variables;
std::getline(inputFile, variables);
std::vector<Block> database;
Block b;
while (inputFile >> b)
{
  database.push_back(b);
}

您可能希望解析变量文本行,然后使用std::map<char, Block>将变量与数据块相关联。