用C语言读把SGY地震数据读成txt

sgy地震数据格式:
文件头总长度为3600字节,分两部分。
1.文件头第一部分
长度: 3200bytes ;组成: 80bytes*40;特性:EBCDIC字符集,参数卡,需要转换为ASCII码后才能显示。
2.文件头第二部分
长度:400bytes;数据类型:32位、16位的整型;特性:二进制头,记录数据体信息。
3.道头 240bytes。
读取:
因为我这里只需要数据,所以直接读头文件有用信息,然后跳过头文件和道头字节,把数据写入txt。

#include "stdio.h" 
#include "stdlib.h" 
#include "string.h" 
#include "math.h" 

float ibm2float(int x);
int swap4byte(int value);

void main()
{
	FILE *filein,*fileout;

	char *inputfile,*outputfile;  //输入输出文件指针
	inputfile = (char*)malloc(sizeof(char)*200);
	outputfile = (char*)malloc(sizeof(char)*200);

	int trace_length = 0;	//道长度(即每道的时间采样点数)
	long int i,len;  //len表示文件的总字节数
	int traces = 0;  //道数 
	unsigned char f3200[3200];
	short int f400[200];

	inputfile = "";  //指定文件,这里需要改成读入绝对路径
	outputfile = "";

	filein = fopen(inputfile,"rb");  //打开文件
	if(filein == NULL)   
	{   
		printf("Can not open File %s\n",inputfile);
		exit(0);
	}
	fileout = fopen(outputfile,"w");
	if(fileout == NULL)   
	{   
		printf("Can not open File %s \n",outputfile);
		exit(0);   
	}

	fread(f3200,3200,1,filein);  //读入3200字节文件头部分  
	fread(f400,200,2,filein);    //读入400字节文件头部分 

	short svalue;
	svalue=((f400[10] & 0xff00)>> 8)|((f400[10] & 0x00ff)<< 8);  //读道长度
	trace_length=svalue; 
	
	fseek(filein,0,2);  
	len=ftell(filein);	//文件长度
	traces=(len-3600)/(240+4L*trace_length);  //计算道数
	printf("len = %d\t traces = %d,trace_length = %d\n",len,traces,trace_length);

	fseek(filein,3600,SEEK_SET);
	char *header;
	header = (char*)malloc(sizeof(char)*240);
	int *data;
	data = (int*)malloc(sizeof(int)*trace_length);
	float *d1;
	d1 = (float*)malloc(sizeof(float)*trace_length);
	int sizeofTraceData = 4L *trace_length ;
	int sizeofTraceHeader = 240;
	int qw1=0;

	for(i=0;i<traces;i++)
	{

		if(i%10000==0)
		{
			printf("%d\n",i);
		}
		fread(header,sizeofTraceHeader,1,filein);  //读道头和数据体
		fread(data,sizeofTraceData,1,filein);
		int j;
		for(j = 0;j < trace_length;j++)
		{
			qw1 = swap4byte(data[j]);
			d1[j] = ibm2float(qw1) ;
			fprintf(fileout,"%f\n",d1[j]);  //把浮点型数据写入文件
		}
	}
	free(data);  //释放内存
	free(header);
	free(d1);
	fclose(filein);  //关闭文件
	fclose(fileout);
}

float ibm2float(int x)
{
	int sign,expo,mantissa,res;
	float result,mant;
	if(x){
		sign = x>>31 & 0x01; //计算IBM浮点数的符号s

		expo = x>>24 & 0x7f; //计算IBM浮点数的指数e

		mantissa = x & 0x00ffffff; //计算IBM浮点数的小数部分f

		if(expo == 127 &&(mantissa & 0x00800000)&& !(mantissa & 0x007fffff)){//判断非数字

			res=(sign<<31)| 0x7f800001;

			memcpy(&result,&res,sizeof(float));

			return result;

		}

		if(expo > 96){    //判断无穷大值

			res =(sign<<31)| 0x7f800000;

			memcpy(&result,&res,sizeof(float));

		}

		else if(expo < 32)result = 0; //判断0值

		else {

			expo = expo-64; //得到指数偏移后的指数e-64

			mant =(float)(mantissa)/ pow(2,24); //转化为十进制小数0.f

			result =(1-2*sign)* mant * pow(16,expo); //带入(2)式中得到十进制数值

		}

		return result; //返回结果
	}
	result = x; //当x=0时,返回0值
	return result;
}

int swap4byte(int value)
{
	int svalue;
	svalue =((value & 0xff000000)>> 24)|((value & 0x00ff0000)>> 8)|

		((value & 0x0000ff00)<< 8)|((value & 0x000000ff)<< 24);

	return svalue;
}

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值