C++阅读多节大文件

x33g5p2x  于 2023-05-19  发布在  其他
关注(0)|答案(1)|浏览(95)

我正试图写一个简单的程序在C++,给出了一个大文件的数据分为几组X,Y,Z,有一个头,其中有写的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`
fiei3ece

fiei3ece1#

我建议重新设计你的程序。
输入文件包含记录块。那么,就这样设计吧。

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

相关问题