读取带有NaN标记的数据格式

来源:互联网 发布:淘宝掌柜名字怎么改 编辑:程序博客网 时间:2024/05/08 22:46

1. 概述

Matlab MappingTools 打包了全球地图数据,从中抽取政区界限、海岸线经纬坐标数据,并保存为文本格式,但其中含有大量的 NaN 标记(注:地图数据的抽取方法将有专文记录)。NaN 意为 Not a Number,可在描绘地图的时候起到分隔轮廓线的作用。

数据示例 theData.txt:

  -16.1080   13.1665
  -16.5489   13.1650
  -16.7854   13.1475
       NaN       NaN
  -13.7319   12.6773
  -13.1625   12.6545
  -12.7934   12.5028
/n/r   注:本行是空行,即仅有 /n/r 的行

  -12.5641   12.4039
  -12.2319   12.3600
  -11.9297   12.3859
  -11.4890   12.4156
  -11.4209   12.3955
       NaN       NaN
  -13.7319   12.6773
  -14.7424   12.6823

以上文件允许任意空行存在。为了让 MFC 应用程序读取这种格式的数据,必须采取一定的方法。

2.可重用代码

2.1 建立数组

数据文件包含的数据多少可能是不确定的,为了获取经纬度坐标数目,首先用一个 Enum 来计数。

ifstream Enum("theData.txt",ios::in);
int HowManyLines;
int LineLength=100;//大于数据文件的每行包含的字符数
char* EnumLine;//用来存放读取的每行数据
EnumLine = new char[LineLength];
while(!Enum.eof())
{
 Enum.getline(EnumLine,LineLength,'/n');//以 /n 为分隔读取每行内容,但什么都不作
 HowManyLines ++;//只是为了计数
}
delete EnumLine;
Enum.close();

double Data**;//以下建立与数据文件相对应的数组
Data = new double*[HowManyLines];
for(int i=0;i<HowManyLines;i++)
{
 Data[i] = new double[2];
}
for(i=0;i<HowManyLines;i++)//以下初始化数组所有元素为0.0
{
 for(int j=0;j<HowManyLines;j++)
  {
   Data[0] = 0.0;
   Data[1] = 0.0;
  }
}

2.2 把数据读入数组

首先要判断某行是否包含 NaN 或者是否空行,如果是,则相应的数组元素赋值为 NULL,如果不是,则读取数据。为了使判断和读取数据不会出现错乱,两者必须并行同时进行,这就需要定义两个 ifstream 对象。

ifstream Try("theData.txt",ios::in);//用于判断
ifstream Read("theData.txt",ios::in);//用于读取数据
char* TryLine;
char* ReadLine;
Cstring Line;

for(i=0;i<HowManyLines;i++)
{
 TryLine = new char[LineLength];
 ReadLine = new char[LineLength];
 Try.getline(TryLine,LineLength,'/n');
 Line = TryLine;

 if(Line.find("NaN")>=0 || TryLine[0]==NULL)//如果包含 NaN 或者是空行
 {
  Data[0] = NULL;
  Data[1] = NULL;//如果满足上面条件,则把经纬度数据都赋值为 NULL。在 MFC 绘图中,NULL 也可起到分隔作用
  Read.getline(ReadLine,LineLength,'/n');
 }
 else
 {
  Read >> Data[0] >> Data[1];
  Read.getline(ReadLine,LineLength,'/n');
 }

 delete TryLine;
 delete ReadLine;
}

Try.close();
Read.close();

3. 说明

尚未知道是否还有更高明的方法。

原创粉丝点击