从 C 文件中读取的数据开头的大数字
Large number at the beginning of data read from a file in C
我有一段代码,我想从 txt 文件中读取列数据。但是,每当我这样做时,一个大数字 - 即 -1.073742e+008 会附加到文件的开头。我不知道它来自哪里或如何摆脱它。由于此片段是一个较大程序的一部分,该程序旨在自动读取文件并将其传递给另一个应用程序,因此不能选择手动删除。我目前的代码如下。
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void main()
{
FILE * fout;
int n;
float f1;
float f2;
float f3;
float npx[5208];
float npy[5208];
float npz[5208];
int v1;
int i;
/*read node cordinates fron the file */
/*char buffer[100];*/
fout = fopen("z1_115k.out", "r");
/*fgets(buffer,100,fout);*/ /* skip the first line*/
while(feof(fout)==0)
{
fscanf(fout, "%d %e %e %e\n", &v1, &f1, &f2, &f3);
npx[v1]=f1;
npy[v1]=f2;
npz[v1]=f3;
}
fclose(fout);
fout = fopen("writeout9.txt" , "w");
for(i=0;i<5208;i++)
{
fprintf(fout, "%e",npy[i]);
fprintf(fout, "\n");
}
fclose(fout);
getch();
}
我正在尝试读取的文件如下所示
1 -1.998999214E-04 -6.326398761E-06 7.987323916E-04
2 -1.993482729E-04 1.613270797E-05 8.020100649E-04
3 -1.998304651E-04 8.233274457E-06 7.735857507E-04
4 -9.247181879E-05 1.772655523E-04 6.779084215E-04
5 -7.928538980E-05 1.833699498E-04 6.915458362E-04
6 -9.789415344E-05 1.918512862E-04 6.868232158E-04
7 -1.943270909E-04 -4.729676220E-05 8.172317175E-04
8 -1.892633736E-04 -6.464808394E-05 8.175745024E-04
第一列的输出如下
-1.073742e+008
-1.998999e-004
-1.993483e-004
-1.998305e-004
-9.247182e-005
-7.928539e-005
-9.789415e-005
-1.943271e-004
-1.892634e-004
为什么我一开始就得到 -1.073e+08 值?
您正在使用文件中最左侧列中给出的索引写入数组。由于这在文件的第一行中以 1 开头,因此条目 #0 将保持未初始化状态。这会导致您在打印 npy[0]
.
时看到垃圾值
此外,与此问题无关,您应该阅读 Why is “while ( !feof (file) )” always wrong? 这可能会导致文件末尾出现错误,以及对错误文件格式的错误处理。您的循环应如下所示:
while (fscanf(fout, "%d %e %e %e\n", &v1, &f1, &f2, &f3) == 4) ...
最后,您可能还想在写入之前检查数组索引是否在范围内。
您的文件以数字 1 开头,因此您访问 npx[1]
。您的打印循环从 0 开始并访问未设置值的 npx[0]
。
第一列是数组索引,这意味着它将从零开始,而不是从一开始。
您可以更改为
while(feof(fout)==0)
{
fscanf(fout, "%d %e %e %e\n", &v1, &f1, &f2, &f3);
npx[v1-1]=f1;
npy[v1-1]=f2;
npz[v1-1]=f3;
}
可能是实际问题:您将值从索引 1
存储到数组,但从索引 0
打印。由于阵列未初始化,您将获得存储在存储单元中的任何内容。您可以从索引读取中减去 1
(推荐,但 先读取 )。或者您打印索引 1
中的值。不推荐,因为您浪费了数组的第一个条目,并且这种行为在 C 和所有其他以 0
作为第一个索引的语言中是不常见的。
但是您的代码还有很多其他问题:
main
的签名不符合 compliant 标准。这会在 return 上调用 未定义的行为 。实际上你的编译器应该警告。
feof
仅检查文件结束指示器是否设置为 来自上一个函数 。它不检查文件本身是否在结尾!
- 始终 检查可能 return 错误条件的函数的结果。
fopen
是这样的函数,scanf
是另外一个!不测试可能会调用 未定义的行为。
- 使用前检查数组索引
v1
!这是来自不可靠的来源(甚至更多,因为你没有检查 fscanf
的结果)并且任何越界访问都会调用 undefined behavior.
- (评论多于问题)
getch
是非标准的。
始终启用编译器警告并留意它们!
注意:在测试期间,最好在读取循环中立即打印在读取循环中读取的值。
我有一段代码,我想从 txt 文件中读取列数据。但是,每当我这样做时,一个大数字 - 即 -1.073742e+008 会附加到文件的开头。我不知道它来自哪里或如何摆脱它。由于此片段是一个较大程序的一部分,该程序旨在自动读取文件并将其传递给另一个应用程序,因此不能选择手动删除。我目前的代码如下。
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void main()
{
FILE * fout;
int n;
float f1;
float f2;
float f3;
float npx[5208];
float npy[5208];
float npz[5208];
int v1;
int i;
/*read node cordinates fron the file */
/*char buffer[100];*/
fout = fopen("z1_115k.out", "r");
/*fgets(buffer,100,fout);*/ /* skip the first line*/
while(feof(fout)==0)
{
fscanf(fout, "%d %e %e %e\n", &v1, &f1, &f2, &f3);
npx[v1]=f1;
npy[v1]=f2;
npz[v1]=f3;
}
fclose(fout);
fout = fopen("writeout9.txt" , "w");
for(i=0;i<5208;i++)
{
fprintf(fout, "%e",npy[i]);
fprintf(fout, "\n");
}
fclose(fout);
getch();
}
我正在尝试读取的文件如下所示
1 -1.998999214E-04 -6.326398761E-06 7.987323916E-04
2 -1.993482729E-04 1.613270797E-05 8.020100649E-04
3 -1.998304651E-04 8.233274457E-06 7.735857507E-04
4 -9.247181879E-05 1.772655523E-04 6.779084215E-04
5 -7.928538980E-05 1.833699498E-04 6.915458362E-04
6 -9.789415344E-05 1.918512862E-04 6.868232158E-04
7 -1.943270909E-04 -4.729676220E-05 8.172317175E-04
8 -1.892633736E-04 -6.464808394E-05 8.175745024E-04
第一列的输出如下
-1.073742e+008
-1.998999e-004
-1.993483e-004
-1.998305e-004
-9.247182e-005
-7.928539e-005
-9.789415e-005
-1.943271e-004
-1.892634e-004
为什么我一开始就得到 -1.073e+08 值?
您正在使用文件中最左侧列中给出的索引写入数组。由于这在文件的第一行中以 1 开头,因此条目 #0 将保持未初始化状态。这会导致您在打印 npy[0]
.
此外,与此问题无关,您应该阅读 Why is “while ( !feof (file) )” always wrong? 这可能会导致文件末尾出现错误,以及对错误文件格式的错误处理。您的循环应如下所示:
while (fscanf(fout, "%d %e %e %e\n", &v1, &f1, &f2, &f3) == 4) ...
最后,您可能还想在写入之前检查数组索引是否在范围内。
您的文件以数字 1 开头,因此您访问 npx[1]
。您的打印循环从 0 开始并访问未设置值的 npx[0]
。
第一列是数组索引,这意味着它将从零开始,而不是从一开始。
您可以更改为
while(feof(fout)==0)
{
fscanf(fout, "%d %e %e %e\n", &v1, &f1, &f2, &f3);
npx[v1-1]=f1;
npy[v1-1]=f2;
npz[v1-1]=f3;
}
可能是实际问题:您将值从索引 1
存储到数组,但从索引 0
打印。由于阵列未初始化,您将获得存储在存储单元中的任何内容。您可以从索引读取中减去 1
(推荐,但 先读取 )。或者您打印索引 1
中的值。不推荐,因为您浪费了数组的第一个条目,并且这种行为在 C 和所有其他以 0
作为第一个索引的语言中是不常见的。
但是您的代码还有很多其他问题:
main
的签名不符合 compliant 标准。这会在 return 上调用 未定义的行为 。实际上你的编译器应该警告。feof
仅检查文件结束指示器是否设置为 来自上一个函数 。它不检查文件本身是否在结尾!- 始终 检查可能 return 错误条件的函数的结果。
fopen
是这样的函数,scanf
是另外一个!不测试可能会调用 未定义的行为。 - 使用前检查数组索引
v1
!这是来自不可靠的来源(甚至更多,因为你没有检查fscanf
的结果)并且任何越界访问都会调用 undefined behavior. - (评论多于问题)
getch
是非标准的。
始终启用编译器警告并留意它们!
注意:在测试期间,最好在读取循环中立即打印在读取循环中读取的值。