C++读取二进制文件,以读取UCAC星表为例

标签:

UCAC(USNO CCD Astrograph Catalog)是美国海军天文台出的一个星表,现在最新的是3.0,用一个双面DVD存储,约7.9G,数据格式为二进制。DVD中有Fortran例子读取文件,本文给出一个C++的实现方式,这也是用C++的方式进行二进制文件读取的例子。

二进制数据格式:

num item   fmt unit        explanation                            remark
------------------------------------------------------------------------
 1  ra     I*4 mas         right ascension at  epoch J2000.0 (ICRS)  (1)
 2  spd    I*4 mas         south pole distance epoch J2000.0 (ICRS)  (1)
 3  im1    I*2 millimag    UCAC fit model magnitude                  (2)
 4  im2    I*2 millimag    UCAC aperture  magnitude                  (2)
 5  sigmag I*2 millimag    UCAC error on magnitude (larger of sc.mod)(3)
 6  objt   I*1             object type                               (4)   
 7  dsf    I*1             double star flag                          (5)   
         16
 8  sigra  I*2 mas         s.e. at central epoch in RA (*cos Dec)      
 9  sigdc  I*2 mas         s.e. at central epoch in Dec                 
10  na1    I*1             total # of CCD images of this star
11  nu1    I*1             # of CCD images used for this star        (6)
12  us1    I*1             # catalogs (epochs) used for proper motions
13  cn1    I*1             total numb. catalogs (epochs) initial match
          8
14  cepra  I*2 0.01 yr     central epoch for mean RA, minus 1900     
15  cepdc  I*2 0.01 yr     central epoch for mean Dec,minus 1900  
16  pmrac  I*4 0.1 mas/yr  proper motion in RA*cos(Dec)           
17  pmdc   I*4 0.1 mas/yr  proper motion in Dec                    
18  sigpmr I*2 0.1 mas/yr  s.e. of pmRA * cos Dec                   
19  sigpmd I*2 0.1 mas/yr  s.e. of pmDec                            
         16
20  id2m   I*4             2MASS pts_key star identifier          
21  jmag   I*2 millimag    2MASS J  magnitude                     
22  hmag   I*2 millimag    2MASS H  magnitude                       
23  kmag   I*2 millimag    2MASS K_s magnitude                     
24  icqflg I*1 * 3         2MASS cc_flg*10 + phot.qual.flag          (7)
25  e2mpho I*1 * 3         2MASS error photom. (1/100 mag)           (8)
         16
26  smB    I*2 millimag    SuperCosmos Bmag
27  smR2   I*2 millimag    SC R2mag                                  (9)
28  smI    I*2 millimag    SC Imag
29  clbl   I*1             SC star/galaxy classif./quality flag     (10)
30  qfB    I*1             SC quality flag Bmag                     (11)
31  qfR2   I*1             SC quality flag R2mag                    (11)
32  qfI    I*1             SC quality flag Imag                     (11)
         10
33  catflg I*1 * 10        mmf flag for 10 major catalogs matched   (12)
34  g1     I*1             Yale SPM object type (g-flag)            (13)
35  c1     I*1             Yale SPM input cat.  (c-flag)            (14)
36  leda   I*1             LEDA galaxy match flag                   (15)
37  x2m    I*1             2MASS extend.source flag                 (16)
38  rn     I*4             MPOS star number; identifies HPM stars   (17)
         18
------------------------------------------------------------------------

C++语言实现:

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

using namespace std;

struct UCAC3
{
	int ra;
	int spd;
	short im1;
	short im2;
	short sigmag;
	char objt;
	char dsf;
	short sigra;
	short sigdc;
	char na1;
	char nu1;
	char us1;
	char cn1;
	short cepra;
	short cepdc;
	int pmrac;
	int pmdc;
	short sigpmr;
	short sigpmd;
	int id2m;
	short jmag;
	short hmag;
	short kmag;
	char icqflg[3];
	char e2mpho[3];
	short smB;
	short smR2;
	short smI;
	char clbl;
	char qfB;
	char qfR2;
	char qfI;
	char catflg[10];
	char g1;
	char c1;
	char leda;
	char x2m;
	int rn;
} ucac;

int main(int argc, char* argv[])
{
	if(argc != 2)
	{
		cout << "Usage: " << argv[0] << " catalog_data" << endl;
		cout << endl << "Version: 0.2" << endl << "Author: HE BOLIANG <hebl@nao.cas.cn" << endl;

		return 0;
	}

	ifstream fin;
	fin.open(argv[1], ios::binary);

	UCAC3 dat;

	while(fin.read((char*)(&dat), sizeof(dat)))
	{		
		cout << setprecision(15) << dat.ra  << "|";
		cout << setprecision(15) << dat.spd << "|";

		cout << dat.im1 << "|" << dat.im2 << "|";
		cout << dat.sigmag << "|";
		cout << (int)dat.objt << "|" << (int)dat.dsf << "|";
		cout << dat.sigra << "|" << dat.sigdc << "|";
		cout << (int)dat.na1 << "|" << (int)dat.nu1 << "|";
		cout << (int)dat.us1 << "|" << (int)dat.cn1 << "|";
		cout << dat.cepra << "|" << dat.cepdc << "|";
		cout << dat.pmrac << "|" << dat.pmdc << "|";
		cout << dat.sigpmr << "|" << dat.sigpmd << "|";
		cout << dat.id2m << "|" ;
		cout << dat.jmag << "|" << dat.hmag << "|" << dat.kmag << "|";
		cout << "[" << (int)dat.icqflg[0] << "," << (int)dat.icqflg[1] << "," 
		     << (int)dat.icqflg[2] << "]|";
		cout << "[" << (int)dat.e2mpho[0] << "," << (int)dat.e2mpho[1] << "," 
		     << (int)dat.e2mpho[2] << "]|";
		cout << dat.smB << "|" << dat.smR2 << "|" << dat.smI << "|";
		cout << (int)dat.clbl << "|" << (int)dat.qfB << "|";
		cout << (int)dat.qfR2 << "|" << (int)dat.qfI << "|";
		cout << "[";
		for(int i=0; i<9; i++)
			cout << (int)dat.catflg[i] << ",";
		cout << (int)dat.catflg[9] << "]|";
		cout << (int)dat.g1 << "|" << (int)dat.c1 << "|";
		cout << (int)dat.leda << "|" << (int)dat.x2m << "|";
		cout << dat.rn << endl;
	}

	fin.close();
	return 0;
}

根据UCAC的数据格式,先定义一个struct,然后读取,需要注意的是,不同的机器可能其数据类型所占的字节数也不同,比如int,在普通的机子上是4个字节,在其他的机子上可能又是不同的位数。这个需要注意