繁体   English   中英

C++ 读取包含多个部分的大文件

[英]C++ reading big file with several section

我正在尝试用 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`

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

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

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>将变量与数据块相关联。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM