提问人:Marc Viernes 提问时间:6/10/2023 最后编辑:OkaMarc Viernes 更新时间:6/11/2023 访问量:64
如何使用输入验证循环从包含一行不同值的数据文件中获取特定值?
How do I obtain specific values from a data file containing a row of different values using an input validation loop?
问:
我想在数据文件上获取一行不同的值,在分别读取前几个值后,然后使用 for 循环读取每个后续值。但是,程序似乎没有读取每个后续值,并且不显示任何内容。我应该如何解决这个问题?
假设这些值如下所示:
4.2 2.0 8.0 3.4 5.1 8.9 7.9
这是我目前拥有的代码:
#include <stdio.h>
int main (void)
{
int i=0,count;
FILE *ptr;
ptr = fopen("datafile.data","r");
fscanf(ptr,"%d ",&count);
double arr[count];
for(i=0;i<count;i++)
{
fscanf(ptr,"%lf ",&arr[i]);
printf("%lf\n",arr[i]);
}
fclose (ptr);
return(0);
}
编辑:%d 的开头应该有一个 5,因此该行看起来像 5 4.2 2.0 8.0 3.4 5.1 8.9 7.9
答:
0赞
amd
6/10/2023
#1
我修复了您的代码中的一些错误,首先是检查文件是否存在,然后将文件的扩展名更改为其次,我从文件中读取值,如下所示。.txt
#include <stdio.h>
int main (void)
{
int i=0,count;
FILE *ptr;
ptr = fopen("datafile.txt","r");
if (ptr == NULL) // check if file exists
{
printf("Error!");
return 1;
}
double buffer[20];
while (fscanf(ptr, "%lf", &buffer[i]) == 1) // read file contents till end of file
{
printf("%.2lf\n", buffer[i]);
i++;
}
return(0);
}
输出
4.20
2.00
8.00
3.40
5.10
8.90
7.90
评论
0赞
Some programmer dude
6/10/2023
不要将 的结果与进行比较,如果存在非数字输入,这将导致无限循环。请改用为条件。fscanf
EOF
fscanf(...) == 1
0赞
Oka
6/11/2023
#2
给定一个输入文件
5
4.2 2.0 8.0 3.4 5.1 8.9 7.9
首先要做的是确保文件已正确打开。
FILE *file = fopen("datafile.data", "r");
if (!file) {
perror("fopen");
exit(1);
}
您必须做的第二件事是确保正确读取初始值,并且处于适当的范围内,以免在创建 VLA 时导致未定义行为。这意味着大于零,并且低于某个合理的限制,以免溢出程序的堆栈(即 等)。ulimit -s
应始终检查的返回值是否为预期的成功转换次数。在这里,我们转换一个值。fscanf
#define MAXSIZE 128
size_t size = 0;
if (1 != fscanf(file, "%zu", &size) || !size || size > MAXSIZE) {
fprintf(stderr, "Invalid size.\n");
return 1;
}
(size_t
是用于内存大小和偏移量的最一般适用类型。
现在,上面的评论
[ ... ]并扫描行末尾的 5 个值,同时跳过 4.2 和 2.0。
引入了一个问题:
除非您的输入始终是静态大小,否则我们怎么知道要跳过多少个值?
如果流是可查找的,一种方法是简单地读取并计算有多少个值。从此计数中减去初始值即可得到要跳过的量。之后,倒带文件并对其进行正确的读取和存储传递。
另一种选择是仅存储读取的最新 N 个值,丢弃以前的值。这可以通过一种循环缓冲区/队列来实现。
一个基本的例子:
double data[size];
size_t total_read = 0;
size_t index = 0;
while (1 == fscanf(file, "%lf", data + index)) {
total_read++;
index = (index + 1) % size;
}
if (total_read < size)
fprintf(stderr, "WARN: Did not read all [%zu] values.\n", size);
之后,如果需要(即顺序很重要和 ),可以通过将缓冲区旋转 来将值返回到其读取顺序。total_read > size
index
评论
fscanf(ptr,"%d ",&count);
fscanf
scanf
fopen
if (!ptr) { perror("Could not open file"); return 1; }