如何解决使用 fgetc 获取 C 中的行数
我的数据如下:
0.05 1.3
0.09 1.8
0.12 1.9
我创建了两个变量 x 和 y 来分别存储它们。
FILE *fp_data;
double *x;
double *y;
int data_size;
char ch;
int i;
fp_data = fopen(path,"r");
while( ( ch = fgetc(fp_data)) != EOF) if(ch=='\n') ++data_size;
if (!fp_data)
{
printf("Data file cannot open...\n");
exit(1);
}
else
{
x = (double*)malloc(data_size * sizeof(double));
y = (double*)malloc(data_size * sizeof(double));
printf("\n%d\n\n",data_size);
for (i = 0; i < data_size; ++i)
{
fscanf(fp_data,"%lf %lf\n",&x[i],&y[i]);
}
fclose(fp_data);
for (i = 0; i < data_size; ++i)
{
printf("%d- %f %f\n",i,x[i],y[i]);
}
}
我注意到我的结果是错误的,例如:
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
但是,如果我删除while( (ch = fgetc(fp_data)) != EOF ) if(ch=='\n') ++data_size;
代码并手动设置 data_size
,则一切正常。
有谁知道fgetc
代码的问题是什么?
解决方法
您的代码中存在一些错误。
首先,你从不初始化 data_size
变量;这是未定义的行为:尽管某些编译器/平台可能将此类“自动”变量的初始值设置为零,但您应该永远不要 靠这个。解决方案:显式在声明时初始化为零:int data_size = 0;
。
其次,在对 fp_data
文件指针进行任何进一步操作之前,您应该检查是否打开文件失败(尽管我找不到明确的提及在 C 标准中,使用 fgetc()
指针调用 NULL
可能会导致未定义的行为)。通过将该检查放在适当的位置,您可以省去 else
条件块(因为如果 exit(1)
调用失败,您的程序会调用 fopen()
)。
第三,您需要在 while ((ch = fgetc(fp_data)) != EOF) ...
循环后将文件指针重置为流的开头!否则,您将尝试从已位于 EOF
的文件中读取数据。您可以使用 rewind()
function 来执行此操作。
第四:注意 fgetc
function 返回的是 int
,而不是 char
;使用 char
类型可能导致检测 EOF
信号的问题
其他要点:
- 不要忘记在使用后
free
分配的内存。 - Do I cast the result of malloc?
- 为了稳健,对
size_t
(和data_size
)使用i
类型。
这是您的代码的版本,其中包含上述要点地址(并已注释):
#include <stdio.h>
#include <stdlib.h>
char path[] = "test.txt"; // Or whatever!
int main()
{
FILE* fp_data;
double* x;
double* y;
size_t data_size = 0; // MUST initialize to zero
int ch; // Note: "fgetc" return an "int" type,not "char"
size_t i;
fp_data = fopen(path,"r");
if (!fp_data) {
printf("Data file cannot open...\n");
exit(1);
}
while ((ch = fgetc(fp_data)) != EOF) if (ch == '\n') ++data_size;
rewind(fp_data); // MUST rewind the file to the beginning,before reading the data!
x = malloc(data_size * sizeof(double));
y = malloc(data_size * sizeof(double));
printf("\n%zu\n\n",data_size);
for (i = 0; i < data_size; ++i) { // Use the "%zu" format for "Size_t" types
fscanf(fp_data,"%lf %lf\n",&x[i],&y[i]);
}
fclose(fp_data);
for (i = 0; i < data_size; ++i) {
printf("%zu- %f %f\n",i,x[i],y[i]);
}
free(x); // Release allocated memory after use.
free(y);
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。