[置顶] WIS文件转换为文本文件的C++源代码

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

 

以下是C++源代码:

 

<textarea cols="50" rows="15" name="code" class="cpp">/* * 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 &lt;windows.h&gt; #include &lt;iostream&gt; #include &lt;iomanip&gt; #include &lt;fstream&gt; #include &lt;string&gt; #include &lt;cstdlib&gt; #include &lt;cctype&gt; #include &lt;ctime&gt; #include &lt;cmath&gt; #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&lt;&lt;"ERROR: Command parameters is not defined correctly!"&lt;&lt;std::endl; exit(1); } wisfile.open(infilename, std::ios::binary); if(!wisfile.is_open()) { std::cerr&lt;&lt;"ERROR: Read file terminated!"&lt;&lt;std::endl; exit(1); } txtfile.open(outfilename); if(!txtfile.is_open()) { std::cerr &lt;&lt; "ERROR: Write file terminated!" &lt;&lt; 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&lt;&lt;"文件标识符: WIS" &lt;&lt; wisid[4] &lt;&lt; wisid[5] &lt;&lt; wisid[6] &lt;&lt; std::endl; txtfile &lt;&lt; "WIS" &lt;&lt; wisid[4] &lt;&lt; wisid[5] &lt;&lt; wisid[6] &lt;&lt; " to ASCII TEXT by SUNYQ/n"; /** 头文件紧接文件标识 */ WIS_HEAD *wishead = new WIS_HEAD; wisfile.seekg(10, std::ios::beg); wisfile.read(reinterpret_cast&lt;char *&gt;(wishead), sizeof(WIS_HEAD)); // 对象入口记录从文件开始的偏移量: wishead-&gt;EntryOffset // 对象数据记录从文件开始的偏移量: wishead-&gt;DataOffset // 当前记录的对象总数: wishead-&gt;ObjectNumber /** 对象入口,位置由头结构中EntryOffset参数指定 最多512条曲线 */ wisfile.seekg(wishead-&gt;EntryOffset, std::ios::beg); delete wishead; /** curvePosition数组 保存曲线数据开始的位置 WIS_OBJECT_ENTRY-&gt;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&lt;char *&gt;(objectEntry), sizeof(WIS_OBJECT_ENTRY)); if(objectEntry-&gt;Attribute == 0) { break; } else if(objectEntry-&gt;Attribute == 1) { // 通道类型: objectEntry-&gt;Attribute // 曲线名字: objectEntry-&gt;Name // 对象数据体绝对偏移量: objectEntry-&gt;Position curvePosition[curveNum] = objectEntry-&gt;Position; int i=0; for(i=0; i&lt;16; i++) { curveName[curveNum][i] = objectEntry-&gt;Name[i]; } curveNum++; } else { continue; } delete objectEntry; } std::cout &lt;&lt; infilename &lt;&lt; " 文件的曲线数目: " &lt;&lt; curveNum &lt;&lt; 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 &lt; curveNum ; num++) // num相当于第几条曲线 { data_head = new CURVE_HEAD; data_head-&gt;position = curvePosition[num]; wisfile.seekg(curvePosition[num], std::ios::beg); WIS_CHANNEL *channel; channel = new WIS_CHANNEL; wisfile.read(reinterpret_cast&lt;char *&gt;(channel), sizeof(WIS_CHANNEL)); data_head-&gt;pointNum = channel-&gt;DimInfo[0].MaxSamples; // 深度采样点的个数 data_head-&gt;startMD = channel-&gt;DimInfo[0].StartVal; // 起始深度 delta = channel-&gt;DimInfo[0].Delta; // 间隔点值 data_head-&gt;stopMD = channel-&gt;DimInfo[0].StartVal + delta * channel-&gt;DimInfo[0].MaxSamples; // 结束深度 int i = 0; for(i=0; i&lt;16; i++) { data_head-&gt;Name[i] = curveName[num][i]; } for(i=0; i&lt;8; i++) { data_head-&gt;Unit[i] = channel-&gt;Unit[i]; } std::cout &lt;&lt; "No." &lt;&lt; num+1 &lt;&lt; "/t"; // 曲线编号 std::cout &lt;&lt; data_head-&gt;Name &lt;&lt; "/t"; // 曲线名 std::cout &lt;&lt; data_head-&gt;Unit &lt;&lt; "/t"; // 曲线单位 std::cout &lt;&lt; data_head-&gt;pointNum &lt;&lt; "/t"; // 采样点数 std::cout &lt;&lt; delta &lt;&lt; "/t"; // 采样点间隔 std::cout &lt;&lt; data_head-&gt;startMD &lt;&lt; "/t"; // 起始深度 std::cout &lt;&lt; data_head-&gt;stopMD &lt;&lt; std::endl; // 结束深度 data_head-&gt;next = first_head; first_head = data_head; } std::cout &lt;&lt; "Waiting..." &lt;&lt; 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-&gt;startMD; maxDepth = first_head-&gt;stopMD; for(data_head = first_head; data_head!= NULL; data_head=data_head-&gt;next) { if(minDepth&gt;data_head-&gt;startMD) { minDepth = data_head-&gt;startMD; // 确定最小深度值 } if(maxDepth &lt; data_head-&gt;stopMD) { maxDepth = data_head-&gt;stopMD; // 确定最大深度值 } } // 利用最小最大深度值和间隔点值,确定输出的采样点数 float depth[ROW]; int lineNum = 0; lineNum = (maxDepth - minDepth) / delta; // 采样点个数:lineNum int row=0; for(row=0; row&lt;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 &lt; curveNum ; num++) { data_node = new CURVE_DATA; int i = 0; for(i=0; i&lt;16; i++) { data_node-&gt;Name[i] = data_head-&gt;Name[i]; // 曲线名称 } for(i=0; i&lt;8; i++) { data_node-&gt;Unit[i] = data_head-&gt;Unit[i]; // 曲线单位 } int startLine = 0; for(row=0; row&lt;lineNum; row++) { if( abs(depth[row]-data_head-&gt;startMD)&lt;= delta &amp;&amp; depth[row] &gt;= data_head-&gt;startMD ) { startLine = row; break; } } // 起始点: startLine wisfile.seekg(data_head-&gt;position+2*sizeof(WIS_CHANNEL)+464, std::ios::beg); // 测试样点数: data_head-&gt;pointNum for(row=0; row&lt;lineNum; row++) { float data[1]; data[0] = -9999.000; if(row&gt;=startLine &amp;&amp; (row-startLine) &lt; data_head-&gt;pointNum) { wisfile.read(reinterpret_cast&lt;char *&gt;(&amp;data), sizeof(float)); data_node-&gt;Depth[row] = data_head-&gt;startMD + delta * (row-startLine); data_node-&gt;Value[row] = data[0]; } else { data_node-&gt;Depth[row] = minDepth + delta * row; data_node-&gt;Value[row] = -9999.000; } // 读取值:data_node-&gt;Value[row] } data_node-&gt;next = first_node; first_node = data_node; if(data_head-&gt;next == NULL) { break; } data_head = data_head-&gt;next; } /* **************************************************** */ /* Below block print all point value for every curve */ /* The important thing is how to decide the right depth */ /* **************************************************** */ // 从这里开始写入文本 // Print Curve Name txtfile &lt;&lt; std::left &lt;&lt; std::setw(12) &lt;&lt; "DEPTH"; for(data_node=first_node; data_node!=NULL; data_node=data_node-&gt;next) { txtfile &lt;&lt; std::left &lt;&lt; std::setw(12) &lt;&lt; data_node-&gt;Name; // txtfile &lt;&lt; " "; } txtfile &lt;&lt; "/n"; // Print Curve Unit txtfile &lt;&lt; std::left &lt;&lt; std::setw(12) &lt;&lt; "M"; for(data_node=first_node; data_node!=NULL; data_node=data_node-&gt;next) { txtfile &lt;&lt; std::left &lt;&lt; std::setw(12) &lt;&lt; data_node-&gt;Unit; } txtfile &lt;&lt; "/n"; // Print curve value for(row=0; row&lt;lineNum; row++) { if(depth[row] &gt; maxDepth) { break; } txtfile &lt;&lt; std::left &lt;&lt; std::setw(12) &lt;&lt; std::setiosflags(std::ios::fixed) &lt;&lt; std::setprecision(3) &lt;&lt; depth[row]; // txtfile &lt;&lt; " "; for(data_node=first_node; data_node!=NULL; data_node=data_node-&gt;next) { txtfile &lt;&lt; std::left &lt;&lt; std::setw(12) &lt;&lt; std::setiosflags(std::ios::fixed) &lt;&lt; std::setprecision(3) &lt;&lt; data_node-&gt;Value[row]; } txtfile &lt;&lt; "/n"; } // */ // Process Over wisfile.close(); txtfile.close(); std::cout &lt;&lt; infilename &lt;&lt; " Complete!" &lt;&lt; std::endl; // system("PAUSE"); // Program Over return 0; } </textarea>

 

你可能感兴趣的:(C++,struct,object,File,table,float)