今天在写代码时,有一个功能是要把文本文件中的浮点型数据读入到二维数组中,数据在文件中是按行存放的,一行数据是一条记录。所以要实现的功能是,将一行数据存入二维数组,作为一行。
在文本文件中,数据是如下面这种方式存储的,每行内的数据之间有空格隔开。
-0.38206 1.29741 0.767442 0.976744 0.963455 0.860465
-0.480132 1.2636 0.764901 0.976821 0.970199 0.817881
-0.382609 1.10577 0.804348 0.986957 0.913043 0.652174
-0.409556 1.23109 0.761092 0.962457 0.972696 0.866894
-0.064516 0.91561 0.870968 0.986175 0.870968 0.635945
要实现这个功能,首先想到的是用最近看过的C++中文件流的方式,主要代码如下:
ifstream infile; //定义读文件流对象
infile.open("1.txt"); //文本文件名为“1.txt”,文件中有30行数据
string s;
int count=0;
float bage[30][6]; //数据要读入的二维数组
while (infile >> s) //逐词读取
{
cout<<s<<" ";
if (count == 5) //每读取6个换行输出
{
cout <<endl;
count = 0;
}
else
count++;
}
之前没用过文件流读取,就先写个输出看看结果如何。结果良好,能够一个数据一个数据的读出,并且是每读一行换行输出。看来自己确实是太久没好好写代码了,连规定读取几个数据,然后换行这样的操作都要做实验来验证。
能够达到预期的逐词读取的效果,并且也不用担心读到行的末尾以及文件末尾时的操作。可是,想要读取到浮点型数组中,而实验是成功读到了字符串中,从字符串类型又没有办法直接转为浮点类型,又是一阵发愁。过了一会,忽然发现,自己真是脑子不够使了:在逐词读取时直接读到浮点型变量中不就可以了,真是笨的可以了。试了一下,果然是可行的。接下来就可以实现功能了:
ifstream infile;
infile.open("1.txt");
int count=0;
int i=0;
float f;
float bage[30][6];
while (infile >> f) //逐词读取
{
bage[i][count]=f;
if (count == 5) //保证每行数据存入二维数组的一行
{
i++;
count=0;
}
else
count++;
}
这样就可以把文本文件中每行的六个数据,读入二维数组中的一行。功能就这样实现了。
接着又用以前的方法把这个功能实现了一下:
FILE *fp;
fp=fopen("1.txt","r");
int i=0;
float bage[30][6];
while (!feof(fp))
fscanf(fp,"%f %f %f %f %f %f",&bage[i][0],&bage[i][1],&bage[i][2],
&bage[i][3],&bage[i][4],&bage[i][5]);
i++;
}
这样也能实现所需要的功能,但存在一个问题,那就是如果最后一行数据之后有空行的话,最后一行会读两遍。原因是:我们用while (!feof(fp))来判断文件是否结束,而feof在遇到文件结束符EOF这个位置是,返回的是0,到下一位置时才返回1,这时while循环才退出。所以只用while循环来判断结束会出现重复现象。怎么办呢?----fscan函数在遇到文件EOF时会返回-1,所以可以把程序中的原fscanf那一行改为:
int flag=fscanf(………..);
if(flag == -1) break;
这样问题就解决了。其实以前用这种方法读文件数据时就遇到了这样的问题,再次遇到的时候已然想不起来当时是怎么解决的了。所以,代码还是要经常写的。