[英]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.