欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C/C++實(shí)現(xiàn)segy文件的讀取詳解

 更新時(shí)間:2022年03月16日 14:15:34   作者:GeoFXR  
SEGY是地震數(shù)據(jù)一般以地震道為單位進(jìn)行組織,采用SEG-Y文件格式存儲(chǔ)。標(biāo)準(zhǔn)SEGY文件一般包括三部分:卷頭、道頭與地震道數(shù)據(jù)。本文將介紹利用C++讀取segy文件的方法,感興趣的可以了解一下

本文檔將介紹SEGY的讀取與寫入過程,其中包括IBM與PC兩種數(shù)據(jù)格式的轉(zhuǎn)換。

程序?qū)⒄{(diào)用IEEE2IBM.cpp文件完成IBM與PC格式的互相轉(zhuǎn)換。

新建頭文件ReadSeismic.h與C++文件ReadSeismic.cpp,以及主程序main.cpp。

1 頭文件ReadSeismic.h的編寫及其規(guī)范

1.1 程序描述、調(diào)用、聲明、定義

/**********************************************************************

 * Copyright(C) 2018,Company All Rights Reserved   (1)版權(quán)說明
   *
 * @file    : ReadSeismic.cpp                      (2) 文件名
   *
 * @brief   :  實(shí)現(xiàn)地震數(shù)據(jù)的讀、寫操作                 (3) 該文件主要功能簡(jiǎn)介
   *
 * @version : 1.0                                  (4) 版本信息
   *
 * @author  : Fan XinRan                           (5) 創(chuàng)建作者
   *
 * @date    : 2022/2/8 星期二                       (6) 創(chuàng)建時(shí)間
   *
 * Others  :                                       (7) 備注、改動(dòng)信息等
   **********************************************************************/
  
//調(diào)用需要的C頭文件
#include<stdio.h>   //C Language header file  
#include<stdlib.h>
#include<string.h>
#include<math.h>

//調(diào)用需要的C++頭文件
#include<iostream>  // C++ header file
#include<vector>
#include<algorithm>

//調(diào)用非標(biāo)準(zhǔn)庫(kù)
#include"alloc.h"   // 用于創(chuàng)建多維數(shù)組
#include"segy.h"   // 包含segy與bhed結(jié)構(gòu)體,用于提取卷頭和道頭中采集、存儲(chǔ)的信息

// 定義全局變量及命名空間
#define PI 3.141592654   //Constant Number Definition
#define EPS 0.0000001

using namespace std;

1.2 聲明函數(shù)

unsigned short exchangeLowHigh16(unsigned short Data_temp);//16位高低位轉(zhuǎn)換函數(shù)  short占2字節(jié),2*8
unsigned int exchangeLowHigh32(unsigned int Data_temp); //32位高低位轉(zhuǎn)換函數(shù)  4*8
float ibm2pc(unsigned int Data_temp);      //IBM轉(zhuǎn)PC數(shù)據(jù)
unsigned int pc2ibm(float input);          //PC轉(zhuǎn)IBM數(shù)據(jù)
float ieee2pc(unsigned int Data_temp);   //IEEE轉(zhuǎn)為PC

void trace_ibm2pc(float *data_output, int *data_input, int nt); //地震道數(shù)據(jù)由IBM轉(zhuǎn)換為PC格式
void trace_pc2ibm(float *data_input, int *data_output, int nt); //地震道數(shù)據(jù)由PC轉(zhuǎn)換為IBM格式

bool copySeismicDataIBM(const char *filenameInput, const char *filenameOutput); //Copy seismic data from Inputfile to Outputfile

1.3完整代碼

/**********************************************************************

 * Copyright(C) 2018,Company All Rights Reserved   
   *
 * @file    : ReadSeismic.cpp                      
   *
 * @brief   :  實(shí)現(xiàn)地震數(shù)據(jù)的讀、寫操作                 
   *
 * @version : 1.0                                  
   *
 * @author  : Fan XinRan                          
   *
 * @date    : 2022/2/8 星期二                       
   *
 * Others  :                                       
   **********************************************************************/

//(1)調(diào)用需要的C頭文件
#include<stdio.h>   // C Language header file  
#include<stdlib.h>
#include<string.h>
#include<math.h>

//(2)調(diào)用需要的C++頭文件
#include<iostream>  // C++ header file
#include<vector>
#include<algorithm>

//(3)調(diào)用需要的非標(biāo)準(zhǔn)庫(kù)頭文件
#include"alloc.h"   // project header file 
#include"segy.h"
#include

//(4)定義全局常量
#define PI 3.141592654   // Constant Number Definition
#define EPS 0.0000001

//(5)聲明命名空間
using namespace std;

//(6)聲明函數(shù)名、輸入、輸出及其類型
unsigned short exchangeLowHigh16(unsigned short Data_temp);//16位高低位轉(zhuǎn)換函數(shù)  short占2字節(jié),2*8
unsigned int exchangeLowHigh32(unsigned int Data_temp); //32位高低位轉(zhuǎn)換函數(shù)  4*8
float ibm2pc(unsigned int Data_temp);      //IBM轉(zhuǎn)PC數(shù)據(jù)
unsigned int pc2ibm(float input);          //PC轉(zhuǎn)IBM數(shù)據(jù)
float ieee2pc(unsigned int Data_temp);   //IEEE轉(zhuǎn)為PC

void trace_ibm2pc(float *data_output, int *data_input, int nt); //地震道數(shù)據(jù)由IBM轉(zhuǎn)換為PC格式
void trace_pc2ibm(float *data_input, int *data_output, int nt); //地震道數(shù)據(jù)由PC轉(zhuǎn)換為IBM格式

bool copySeismicDataIBM(const char *filenameInput, const char *filenameOutput); //Copy seismic data from Inputfile to Outputfile

2 C++文件ReadSeismic.cpp的編寫及其規(guī)范

2.1 必要的說明

/*************************************************************************************************************

 Function:       copySeismicDataIBM                                                (1)函數(shù)名
 Description:    copy segy file from input data to output data                     (2)簡(jiǎn)要描述其功能
 Input:          
                 const char *filenameInput [in]    input filename (.segy)          (3)輸入變量及輸入文件類型
 Output:         
                 const char  *filenameOutput[out]  output filename (.segy)         (4)輸出變量及輸出文件類型
 Return:         
             bool  true    program success
			 bool  false   program failed                                          (5)返回值及其說明
 Author:     Fan XinRan                                                            (6)創(chuàng)建作者
 Date  :     2022/2/8                                                              (7)創(chuàng)建時(shí)間
 Others:                                                                           (8)備注、改動(dòng)信息等
 
*************************************************************************************************************/

2.2 定義讀、寫函數(shù)

#include "ReadSeismic.h"
bool copySeismicDataIBM(const char *filenameInput, const char *filenameOutput){

    //實(shí)現(xiàn)代碼        
    ...

}

(1)定義待使用的結(jié)構(gòu)體變量、數(shù)值型變量

bhed 與 segy均為定義在segy.h中的結(jié)構(gòu)體(structure),分別包含了二進(jìn)制卷頭信息與道頭信息,使用成員訪問運(yùn)算符(.)獲取其內(nèi)容;

使用unsigned int 聲明整型變量,使用long long 或__int64聲明SEGY文件字節(jié)數(shù)、地震道字節(jié)數(shù),防止數(shù)據(jù)量超出范圍,并且盡可能初始化變量。

bhed fileheader;        // file header  卷頭
segy traceheader;       // trace header  道頭
unsigned int nt=0;        // number of sample  采樣點(diǎn)數(shù)
unsigned int sizefileheader=sizeof(fileheader);   // size of fileheader;
unsigned int sizetraceheader=sizeof(traceheader);  // size of traceheader;

unsigned int ncdp = 0;      // number of cdp  道數(shù)
long long  size_file = 0;   //size of input file
long long  size_trace = 0;  //size of per-trace

(2)新建指針變量

在讀、寫地震道數(shù)據(jù)這一任務(wù)中,需要用到輸入指針、輸出指針、地震道數(shù)據(jù)指針、道頭指針以及一個(gè)臨時(shí)指針變量,共五個(gè)指針變量。

FILE *fpinput = NULL;   // input file pointer
FILE *fpoutput = NULL;   // output file pointer
float *dataInput = NULL;  // input data pointer
segy *traceheaderArray = NULL; // traceheader pointer
int* temp = NULL;  // temp pointer 

之前的任務(wù)中fread(dataInput[itrace],nt * sizeof(float),1,fpinput),

整個(gè)讀、寫流程為:fpinput-->讀取nt個(gè)數(shù)據(jù)-->dataInput[itrace]-->寫入nt個(gè)數(shù)據(jù)-->fpoutput

本次任務(wù)中需要對(duì)數(shù)據(jù)進(jìn)行變換,流程變?yōu)椋?code>fpinput-->讀取nt個(gè)數(shù)據(jù)-->temp-->IBM/PC轉(zhuǎn)換-->dataInput[itrace]-->寫入nt個(gè)數(shù)據(jù)-->fpoutput。

(3)打開輸入、輸出文件指針

fpinput = fopen(filenameInput, "rb");  //open input file pointer 
fpoutput = fopen(filenameOutput,"wb");  //open output file pointer

//讀寫操作
...
    
//fopen()與fclose()成對(duì)出現(xiàn),在對(duì)文件的操作完成后切記關(guān)閉文件
fclose(fpinput);  //close input file pointer
fclose(fpoutput); //close output file pointer

(4)判斷文件打開情況

if(fpinput==NULL){                                            //如果文件指針為NULL
	printf("Cannot open %s file\n", filenameInput);           //打印“文件打開失敗”
	return false;                                             //結(jié)束程序
}

if(fpoutput==NULL){
	printf("Cannot open %s file\n", filenameOutput);
	return false;
}

(5)讀取/計(jì)算卷、道信息

fread(&fileheader,sizefileheader,1,fpinput); // 從輸入流(fpinput)中讀取卷頭信息到指定地址---->fileheader

nt = exchangeLowHigh16(fileheader.hns) // 高低位轉(zhuǎn)換

_fseeki64(fpinput,0,SEEK_END);   // 從文件末尾偏移這個(gè)結(jié)構(gòu)體0個(gè)長(zhǎng)度給文件指針fpinput,即fpinput此時(shí)指向文件尾

size_file = _ftelli64(fpinput);  // 返回當(dāng)前文件位置,即文件總字節(jié)數(shù)
size_trace = nt*sizeof(float)+sizetraceheader;  // 每一道的字節(jié)數(shù) = 采樣點(diǎn)字節(jié)數(shù)+道頭字節(jié)數(shù)

ncdp = (size_file - (long long)sizefileheader)/size_trace; // 道數(shù) = (文件總字節(jié)數(shù) - 卷頭字節(jié)數(shù))/每一道的字節(jié)數(shù)

_fseeki64(fpinput,sizefileheader,SEEK_SET); // 從文件開頭偏移sizefileheader(卷頭字節(jié)數(shù))個(gè)長(zhǎng)度給指針fpinput,即fpinput此時(shí)指向第一道的開始
fwrite(&fileheader, sizefileheader, 1, fpoutput); // 先寫入卷頭
  • fread() 從給定流讀取數(shù)據(jù)到指針?biāo)赶虻臄?shù)組中;
  • fwrite(*ptr, size, nmemb,*stream) 參數(shù)與fread()相同,把ptr所指向的數(shù)組中的數(shù)據(jù)寫入到給定流stream中;
  • _fseeki64的用法與fseek相同,表示從文件指定位置偏移一定字節(jié)數(shù);前者具有更高的兼容性;
  • _ftelli64ftell同理,返回給定流的當(dāng)前文件位置;
  • exchangeLowHigh16()完成short型的高低位轉(zhuǎn)換,int型的高低位轉(zhuǎn)換使用exchangeLowHigh64()。

(6)遍歷每一條地震道,讀、寫數(shù)據(jù)

dataInput=alloc2float(nt,ncdp); // 分配nt*ncdp(采樣點(diǎn)數(shù)×道數(shù))所需的內(nèi)存空間,用來存放二維地震道數(shù)據(jù)
//其中,alloc2float是卸載alloc.h中的函數(shù),創(chuàng)建一個(gè)float型的二維數(shù)組
//dataInput為二級(jí)指針,可簡(jiǎn)記為dataInput指向每一行的開頭

memset(dataInput[0], 0, nt*ncdp * sizeof(float)); // 從第一行的開頭開始,將內(nèi)存塊中nt*ncdp個(gè)字符賦值為0
// dataInput指向每行開頭,而dataInput[0]則為整個(gè)二維數(shù)組的起始位置

// 在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中分配ncdp個(gè)長(zhǎng)度為sizetraceheader的連續(xù)空間
traceheaderArray = (segy*)calloc(ncdp,sizetraceheader);

temp = (int*)calloc(nt,sizeof(int));

//逐道讀取道頭與地震道數(shù)據(jù)
for(int itrace = 0; itrace < ncdp; itrace++){
    fread(&traceheaderArray[itrace],sizetraceheader,1,fpinput); // &traceheaderArray[itrace]為第itrace道的地址,讀取該道頭信息
    fread(temp,nt * sizeof(float),1,fpinput); // 讀取nt個(gè)采樣點(diǎn)的信息并將結(jié)果指向temp
    
    // 使用trace_ibm2pc將temp位置后nt個(gè)采樣點(diǎn)的數(shù)據(jù),進(jìn)行IBM-->PC的轉(zhuǎn)換,結(jié)果指向每一道開頭(dataInput[itrace])
    trace_ibm2pc(dataInput[itrace], temp, nt); 
    
}//end for(int itrace = 0; itrace < ncdp; itrace++)

//逐道寫入道頭與地震道數(shù)據(jù)
for (int itrace = 0; itrace < ncdp; itrace++) {
    fwrite(&traceheaderArray[itrace], sizetraceheader, 1, fpoutput); // 寫入該道頭信息
    
    // 使用trace_pc2ibm將temp位置后nt個(gè)采樣點(diǎn)的數(shù)據(jù),進(jìn)行PC-->IBM的轉(zhuǎn)換,結(jié)果指向每一道開頭(dataInput[itrace])
    trace_pc2ibm(dataInput[itrace],temp,nt); 
    
    fwrite(temp, nt * sizeof(int), 1, fpoutput); // 以IBM的格式存回fpoutput
}//end for(int itrace = 0; itrace < ncdp; itrace++)
 // 在每個(gè)循環(huán)末尾的"}"添加備注,便于尋找和區(qū)分

//在寫操作完成后釋放內(nèi)存
free(temp); // free temp pointer
free(traceheaderArray); // free traceheader pointer
free2float(dataInput);  // free data input pointer
  • calloc(num,size):在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中分配num個(gè)長(zhǎng)度為size的連續(xù)空間,函數(shù)返回一個(gè)指向分配起始地址的指針;如果分配不成功,返回NULL;
  • malloc(size):功能與calloc()相似,不同之處是malloc() 不會(huì)將內(nèi)存值初始化為0,而 calloc()會(huì)將新申請(qǐng)的內(nèi)存填充0。

2.3完整代碼

/*****************************************************************************
 Function:       CopySeismicData                                              
 Description:    copy segy file from input data to output data                   
 Input:          
                 const char *filenameInput [in]    input filename (.segy)         
 Output:         
                 const char  *filenameOutput[out]  output filename (.segy)        
 Return:         
             bool  true    program success
			 bool  false   program failed                                         
 Author:     Fan XinRan                                                         
 Date  :     2022/2/8                                                             
 Others:                                                                           
*****************************************************************************/
#include "ReadSeismic.h"

bool copySeismicDataIBM(const char *filenameInput, const char *filenameOutput){

	segy traceheader;       // trace header 
	bhed fileheader;        // file header
	unsigned int nt = 0;        // number of sample
	unsigned int sizetraceheader = sizeof(traceheader);  // size of traceheader;
	unsigned int sizefileheader = sizeof(fileheader);   // size of fileheader;
	unsigned int ncdp = 0;     // number of cdp
	long long   size_file = 0;  //size of input file
	long long  size_trace = 0;  //size of per-trace

	FILE *fpinput = NULL;   // input file pointer
	FILE *fpoutput = NULL;   //output file pointer
	float **dataInput = NULL;  //input data pointer
	segy *traceheaderArray = NULL; //
	int* temp = NULL;

	fpinput = fopen(filenameInput, "rb");  //open input file pointer 
	fpoutput = fopen(filenameOutput, "wb");  //open output file pointer


	if (fpinput == NULL) {
		printf("Cannot open %s file\n", filenameInput);
		return false;
	}

	if (fpoutput == NULL) {
		printf("Cannot open %s file\n", filenameOutput);
		return false;
	}

	fread(&fileheader, sizefileheader, 1, fpinput);

	nt = fileheader.hns;
	nt = exchangeLowHigh16(fileheader.hns);
	_fseeki64(fpinput, 0, SEEK_END);
	size_file = _ftelli64(fpinput);
	size_trace = nt * sizeof(float) + sizetraceheader;

	ncdp = (size_file - (long long)sizefileheader) / size_trace;

	_fseeki64(fpinput, sizefileheader, SEEK_SET);


	dataInput = alloc2float(nt, ncdp);
	memset(dataInput[0], 0, nt*ncdp * sizeof(float));
	traceheaderArray = (segy*)calloc(ncdp, sizetraceheader);

	temp = (int*)calloc(nt,sizeof(int));


	fwrite(&fileheader,sizefileheader,1, fpoutput);
	for (int itrace = 0; itrace < ncdp; itrace++) {

		fread(&traceheaderArray[itrace], sizetraceheader, 1, fpinput);
		fread(temp, nt * sizeof(int), 1, fpinput);
		trace_ibm2pc(dataInput[itrace], temp, nt);
	}//end for(int itrace = 0; itrace < ncdp; itrace++)

	for (int itrace = 0; itrace < ncdp; itrace++) {
		fwrite(&traceheaderArray[itrace], sizetraceheader, 1, fpoutput);
		trace_pc2ibm(dataInput[itrace],temp,nt);
		fwrite(temp, nt * sizeof(int), 1, fpoutput);
	}//end for(int itrace = 0; itrace < ncdp; itrace++)


	free(temp);
	free(traceheaderArray);
	free2float(dataInput);  // free data input pointer
	fclose(fpoutput); //close output file pointer
	fclose(fpinput);  //close input file pointer
	return true;
}

3 主函數(shù)main.cpp及運(yùn)行結(jié)果

#include"ReadSeismic.h"

void main(){

	copySeismicDataIBM("Azi6-Ang35-BZ19-6-1.segy","Outputibm.segy");

}

運(yùn)行主函數(shù)后,程序會(huì)讀入Azi6-Ang35-BZ19-6-1.segy,這是一個(gè)IBM格式的數(shù)據(jù)。再寫入到Outputibm.segy,從而完成對(duì)SEGY文件的復(fù)制。

以上就是C/C++實(shí)現(xiàn)segy文件的讀取詳解的詳細(xì)內(nèi)容,更多關(guān)于C++讀取segy文件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單學(xué)生選課管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單學(xué)生選課管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單學(xué)生選課管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • 淺析C++中strlen函數(shù)的使用與模擬實(shí)現(xiàn)strlen的方法

    淺析C++中strlen函數(shù)的使用與模擬實(shí)現(xiàn)strlen的方法

    這篇文章主要介紹了strlen函數(shù)的使用與模擬實(shí)現(xiàn)strlen的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • C語(yǔ)言實(shí)現(xiàn)房屋管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)房屋管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)房屋管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • C++關(guān)于指針,繼承和多態(tài)介紹

    C++關(guān)于指針,繼承和多態(tài)介紹

    大家好,本篇文章主要講的是C++關(guān)于指針,繼承和多態(tài)介紹,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • C語(yǔ)言實(shí)現(xiàn)密碼本

    C語(yǔ)言實(shí)現(xiàn)密碼本

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)密碼本,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • C++實(shí)現(xiàn)LeetCode(22.生成括號(hào))

    C++實(shí)現(xiàn)LeetCode(22.生成括號(hào))

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(22.生成括號(hào)),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 你真的理解C語(yǔ)言qsort函數(shù)嗎?帶你深度剖析qsort函數(shù)

    你真的理解C語(yǔ)言qsort函數(shù)嗎?帶你深度剖析qsort函數(shù)

    這篇文章主要介紹了你真的理解C語(yǔ)言qsort函數(shù)嗎?帶你深度剖析qsort函數(shù),本篇將引入一個(gè)庫(kù)函數(shù)來實(shí)現(xiàn)我們希望的順序,結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • C++實(shí)現(xiàn)LeetCode(309.買股票的最佳時(shí)間含冷凍期)

    C++實(shí)現(xiàn)LeetCode(309.買股票的最佳時(shí)間含冷凍期)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(309.買股票的最佳時(shí)間含冷凍期),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C語(yǔ)言實(shí)現(xiàn)手機(jī)電話簿管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)手機(jī)電話簿管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)手機(jī)電話簿管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C++關(guān)于字符的接收與輸出操作示例

    C++關(guān)于字符的接收與輸出操作示例

    這篇文章主要介紹了C++關(guān)于字符的接收與輸出操作,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-01-01

最新評(píng)論