您的位置:首页 > 编程语言 > C语言/C++

WIS文件转换为文本文件的C++源代码

2011-04-25 18:07 274 查看
我在上一篇文章中描述了wis二进制文件的结构(wis是石油测井软件Forward中的一种二进制文件格式,很多软件需要转换为文本才可使用),然后用纯C编写了转换程序,利用Python编写了界面调用这个程序,在这里我利用C++重新编写了这个程序,当然和C编写的区别不大,主要的区别在内存分配、读取二进制文件和写入文本文件的函数上,也是为了说明C与C++文件操作上的一些区别,有兴趣的朋友可以和上一遍文章对比一下,技术有限,仅供参考!

以下是C++源代码:

/*
* Copyright (c) 2011, Sun Yunqiang
* All rights reserved.
* Software: wis2txt_win.cpp
* Version: 1.0
* Author: Sun Yunqiang
* English Name: Alex Sun
* Release Date: 18/03/2011
*/

/** ***************************************************************** */
/** This Program is for converting wis format file to txt format file */
/** Command: wis2txt_win.exe  args1  args2                            */
/** Description:                                                      */
/**              wis2txt_win.exe: the executable file as command      */
/**              args1: the first argument that is the wis file name  */
/**              args2: the second argument that is the txt file name */
/** ***************************************************************** */

#include <windows.h>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cctype>
#include <ctime>
#include <cmath>

#define ROW 65536
#define COL 512

/* **************************************** */
/* Below blocks are the structs of wis file */
/* **************************************** */
typedef struct tagWIS_HEAD
{
WORD  MachineType;  // 0-PC  1-SUN   2-IBM	3-HP
WORD  MaxObjectNumber;
WORD  ObjectNumber;
WORD  BlockLen;
DWORD EntryOffset;
DWORD DataOffset;
DWORD FileSize;
time_t TimeCreate;
char  Reserved[32];
}WIS_HEAD;

typedef struct tagWIS_OBJECT_ENTRY
{
char   Name[16];
long   Status;
short  Attribute;      // 1-通道对象 2-表对象 3-流对象
short  SubAttribute;   // 1-曲线对象 2-波形对象 3-地层测试对象 4-时深时对象
DWORD  Position;       // 对象数据体从文件开始处的偏移量
DWORD  BlockNum;
time_t TimeCreate;
time_t TimeWrite;
char  Reserved[32];
}WIS_OBJECT_ENTRY;

typedef struct tagWIS_CHANNEL_DIMENSION
{
char   Name[8];
char   Unit[8];
char   AliasName[16];
float  StartVal;
float  Delta;
DWORD  Samples;
DWORD  MaxSamples;
DWORD  Size;
WORD   RepCode;
WORD   Reserved;
}WIS_CHANNEL_DIMENSION;

typedef struct tagWIS_CHANNEL
{
char   Unit[8];
char   AliasName[16];
char   AliasUnit[16];
WORD   RepCode;
WORD   CodeLen;
float  MinVal;
float  MaxVal;
WORD   Reserved;
WORD   NumOfDimension;
WIS_CHANNEL_DIMENSION DimInfo[4];
}WIS_CHANNEL;

typedef struct tagWIS_STREAM
{
DWORD Length;
DWORD Offset;
}WIS_STREAM;

typedef struct tagWIS_TABLE_FIELD
{
char   Name[32];
WORD   RepCode;
WORD   Length;
DWORD  Reserved;
} WIS_TABLE_FIELD;

typedef struct tagWIS_TABLE
{
DWORD  RecordCount;
DWORD  FieldCount;
WIS_TABLE_FIELD *pField;
}WIS_TABLE;

typedef struct tagWIS_TABLE_DEFAULT_FILED
{
char   Name[16];
char   Alias[16];
char   Unit[8];
char   Type[8];
WORD   Length;
WORD   Count;
char   DefVal[64][12];
} WIS_TABLE_DEFAULT_FIELD;

typedef struct tagWIS_DEFAULT_TABLE
{
char   Name[16];
char   Alias[16];
char   Attrb[8];
DWORD  FieldCount;
WIS_TABLE_DEFAULT_FIELD *pField;
} WIS_DEFAULT_TABLE;

/* 曲线的信息结构体*/
typedef struct tagCURVE_HEAD
{
char   Name[16];        // 曲线的名字
char   Unit[8];         // 曲线的单位
float  startMD;         // 曲线的起始深度
float  stopMD;          // 曲线的结束深度
int    pointNum;        // 数据样点数
int    position;        // 数据位置
struct tagCURVE_HEAD  *next;
} CURVE_HEAD;

/* 曲线的数据结构体 */
typedef struct tagCURVE_DATA
{
char   Name[16];        // 曲线的名字
char   Unit[8];         // 曲线的单位
float  Depth[ROW];      // 曲线的深度值
float  Value[ROW];      // 曲线的值
struct tagCURVE_DATA  *next;
} CURVE_DATA;

/* ************************************************************* */
/* Below block is the Main program of processing wis format file */
/* ************************************************************* */

int main(int argc, char *argv[])
{
std::ifstream wisfile;        // 输入文件
std::ofstream txtfile;        // 输出文件
char *infilename = argv[1];
char *outfilename = argv[2];
// char *infilename = "demoa.wis";
// char *outfilename = "demoa.txt";

if(argc != 3 )
{
std::cerr<<"ERROR: Command parameters is not defined correctly!"<<std::endl;
exit(1);
}

wisfile.open(infilename, std::ios::binary);
if(!wisfile.is_open())
{
std::cerr<<"ERROR: Read file terminated!"<<std::endl;
exit(1);
}

txtfile.open(outfilename);
if(!txtfile.is_open())
{
std::cerr << "ERROR: Write file terminated!" << std::endl;
exit(1);
}

/* Process wis file, Read it and transfer it to text */

/** wis文件标识符从文件偏移0开始,为10个字节的字符 */
char wisid[10];
wisfile.read(wisid, 10);
std::cout<<"文件标识符: WIS" << wisid[4] << wisid[5] << wisid[6] << std::endl;
txtfile << "WIS" << wisid[4] << wisid[5] << wisid[6] << " to ASCII TEXT by SUNYQ/n";

/** 头文件紧接文件标识 */
WIS_HEAD *wishead = new WIS_HEAD;
wisfile.seekg(10, std::ios::beg);
wisfile.read(reinterpret_cast<char *>(wishead), sizeof(WIS_HEAD));
// 对象入口记录从文件开始的偏移量: wishead->EntryOffset
// 对象数据记录从文件开始的偏移量: wishead->DataOffset
// 当前记录的对象总数: wishead->ObjectNumber

/** 对象入口,位置由头结构中EntryOffset参数指定 最多512条曲线 */
wisfile.seekg(wishead->EntryOffset, std::ios::beg);
delete wishead;

/** curvePosition数组 保存曲线数据开始的位置 WIS_OBJECT_ENTRY->Position的值 */
/** curveName数组 保存每条曲线的名称 */
/** curveNum变量 文件中保存曲线的数目 */
int curvePosition[512];
int curveName[512][16];
int curveNum = 0;  // curveNum is the identifer of the curves number

while(1)
{
WIS_OBJECT_ENTRY *objectEntry;
objectEntry = new WIS_OBJECT_ENTRY;
wisfile.read(reinterpret_cast<char *>(objectEntry), sizeof(WIS_OBJECT_ENTRY));

if(objectEntry->Attribute == 0)
{
break;
}
else if(objectEntry->Attribute == 1)
{
// 通道类型: objectEntry->Attribute
// 曲线名字: objectEntry->Name
// 对象数据体绝对偏移量: objectEntry->Position
curvePosition[curveNum] = objectEntry->Position;
int i=0;
for(i=0; i<16; i++)
{
curveName[curveNum][i] = objectEntry->Name[i];
}

curveNum++;
}
else
{
continue;
}

delete objectEntry;

}
std::cout << infilename << " 文件的曲线数目: " << curveNum << std::endl;

/* ****************************************************************** */
/* Below block read every curve head information and put it in a link */
/* ****************************************************************** */

/** 创建链表 data_node 开始读取数据 */
/** num变量 每条曲线的行数 */
CURVE_HEAD *first_head = NULL;
float delta = 0.0;

CURVE_HEAD *data_head = NULL;
int num = 0;
for(num = 0; num < curveNum ; num++)   // num相当于第几条曲线
{

data_head = new CURVE_HEAD;
data_head->position = curvePosition[num];

wisfile.seekg(curvePosition[num], std::ios::beg);
WIS_CHANNEL *channel;
channel = new WIS_CHANNEL;
wisfile.read(reinterpret_cast<char *>(channel), sizeof(WIS_CHANNEL));

data_head->pointNum = channel->DimInfo[0].MaxSamples;   // 深度采样点的个数
data_head->startMD = channel->DimInfo[0].StartVal;      // 起始深度
delta = channel->DimInfo[0].Delta;              //  间隔点值
data_head->stopMD = channel->DimInfo[0].StartVal + delta * channel->DimInfo[0].MaxSamples;  // 结束深度

int i = 0;
for(i=0; i<16; i++)
{
data_head->Name[i] = curveName[num][i];
}
for(i=0; i<8; i++)
{
data_head->Unit[i] = channel->Unit[i];
}

std::cout << "No." << num+1 << "/t";           // 曲线编号
std::cout << data_head->Name << "/t";          // 曲线名
std::cout << data_head->Unit << "/t";          // 曲线单位
std::cout << data_head->pointNum << "/t";      // 采样点数
std::cout << delta << "/t";                    // 采样点间隔
std::cout << data_head->startMD << "/t";       // 起始深度
std::cout << data_head->stopMD << std::endl;   // 结束深度

data_head->next = first_head;
first_head = data_head;
}
std::cout << "Waiting..." << std::endl;

/* *********************************************************************** */
/* Below block is for deciding the min and max Depth, and the max line num */
/* *********************************************************************** */

// 从这里开始判断所有曲线中最小深度和最大深度值
float minDepth = 0.0;
float maxDepth = 0.0;
minDepth = first_head->startMD;
maxDepth = first_head->stopMD;
for(data_head = first_head; data_head!= NULL; data_head=data_head->next)
{
if(minDepth>data_head->startMD)
{
minDepth = data_head->startMD;    // 确定最小深度值
}
if(maxDepth < data_head->stopMD)
{
maxDepth = data_head->stopMD;    // 确定最大深度值
}
}

// 利用最小最大深度值和间隔点值,确定输出的采样点数
float depth[ROW];
int lineNum = 0;
lineNum = (maxDepth - minDepth) / delta;
// 采样点个数:lineNum

int row=0;
for(row=0; row<lineNum; row++)
{
depth[row] = minDepth + delta * row;
}

/* ******************************************************** */
/* Below block put every point value into a link as a curve */
/* ******************************************************** */

// 从这里开始将数据值放入曲线各自对应的链表里

CURVE_DATA *first_node = NULL;
CURVE_DATA *data_node = NULL;

data_head = first_head;

for(num = 0; num < curveNum ; num++)
{
data_node = new CURVE_DATA;
int i = 0;
for(i=0; i<16; i++)
{
data_node->Name[i] = data_head->Name[i];  // 曲线名称
}
for(i=0; i<8; i++)
{
data_node->Unit[i] = data_head->Unit[i];    // 曲线单位
}

int startLine = 0;
for(row=0; row<lineNum; row++)
{
if( abs(depth[row]-data_head->startMD)<= delta
&& depth[row] >= data_head->startMD )
{
startLine = row;
break;
}
}
// 起始点: startLine

wisfile.seekg(data_head->position+2*sizeof(WIS_CHANNEL)+464, std::ios::beg);

// 测试样点数: data_head->pointNum
for(row=0; row<lineNum; row++)
{
float data[1];
data[0] = -9999.000;
if(row>=startLine && (row-startLine) < data_head->pointNum)
{
wisfile.read(reinterpret_cast<char *>(&data), sizeof(float));
data_node->Depth[row] = data_head->startMD + delta * (row-startLine);
data_node->Value[row] = data[0];
}
else
{
data_node->Depth[row] = minDepth + delta * row;
data_node->Value[row] = -9999.000;
}

// 读取值:data_node->Value[row]
}

data_node->next = first_node;
first_node = data_node;
if(data_head->next == NULL)
{
break;
}

data_head = data_head->next;
}

/* **************************************************** */
/* Below block print all point value for every curve    */
/* The important thing is how to decide the right depth */
/* **************************************************** */

// 从这里开始写入文本

// Print Curve Name
txtfile << std::left << std::setw(12) << "DEPTH";
for(data_node=first_node; data_node!=NULL; data_node=data_node->next)
{
txtfile << std::left << std::setw(12) << data_node->Name;
// txtfile << "    ";
}
txtfile << "/n";

// Print Curve Unit
txtfile << std::left << std::setw(12) << "M";
for(data_node=first_node; data_node!=NULL; data_node=data_node->next)
{
txtfile << std::left << std::setw(12) << data_node->Unit;
}
txtfile << "/n";

// Print curve value
for(row=0; row<lineNum; row++)
{
if(depth[row] > maxDepth)
{
break;
}
txtfile << std::left << std::setw(12) << std::setiosflags(std::ios::fixed)
<< std::setprecision(3) << depth[row];
// txtfile << "    ";
for(data_node=first_node; data_node!=NULL; data_node=data_node->next)
{
txtfile << std::left << std::setw(12) << std::setiosflags(std::ios::fixed)
<< std::setprecision(3) << data_node->Value[row];
}
txtfile << "/n";
}
// */

// Process Over
wisfile.close();
txtfile.close();

std::cout << infilename << " Complete!" << std::endl;
// system("PAUSE");
// Program Over
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: