【问题标题】:fscanf not reading floats correctlyfscanf 没有正确读取浮点数
【发布时间】:2013-01-31 04:15:09
【问题描述】:

---这是一道作业题---

我在使用 fscanf 从文本文件中读取浮点值时遇到问题。

基本上我正在尝试从文件中读取浮点值并将它们存储在动态数组中。 输入文件每行有两个浮点数。所以一行可能是“0.85 7.34”(不带引号)。所以我尝试使用 fscanf(fp, "%f %f", &coordinates[i], &coordinates[i++]) 来读取 2 个浮点值。当我打印它显示为 0.00000。下面是我编写的代码和它产生的输出。

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv []) {

FILE * fp = fopen("nums", "r");

float *coordinates;
float *tmp;
int i = 0;
int ARRAY_SIZE = 5;
coordinates = malloc(5*sizeof(float));

while (fscanf(fp,"%f %f", &coordinates[i], &coordinates[i++]) > 1)
{

  printf("iteration# %d | coord1 = %f coord2 = %f \n", i, &coordinates[i-1], &coordinates[i]);

  if (i >= ARRAY_SIZE)
  {
    tmp = realloc(coordinates, (i*2)*sizeof(float));
    coordinates = tmp;
    ARRAY_SIZE = i*2;
  }
  i++;
}

for(i = 0; i < 8; i++)
  printf("%f\n", &coordinates[i]);


return 0;
}

输出:

iteration# 1 | coord1 = 0.000000 coord2 = 0.000000 
iteration# 3 | coord1 = 0.000000 coord2 = 0.000000 
iteration# 5 | coord1 = 0.000000 coord2 = 0.000000 
iteration# 7 | coord1 = 0.000000 coord2 = 0.000000 
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000  

【问题讨论】:

  • 小心。 fscanf(fp,"%f %f", &amp;coordinates[i], &amp;coordinates[i++]) 是未定义的行为,因为您无法保证 coordinates[i] 是否在 coordinates[i++] 之前或之后进行评估,因此您可能会混淆(因为当您认为i 可能不会增加时)!未指定 args 的评估顺序。
  • 所以你的意思是 i 可以在计算坐标[i] 之前递增?
  • 是的,这是可能的。另外,您可能想要++i 而不是i++(假设参数按照您想要的顺序进行评估,但事实并非如此)。在 C 中,前增量和后增量之间存在差异。实际上,也许你真正想要的是i++ 。但是,评估的顺序是不确定的。

标签: c scanf


【解决方案1】:

您不要将“地址”-运算符&amp;printf 一起使用。 fscanf 需要一个指向数据的指针,以便它知道可以更改变量值,而 printf 不能。

变化:

printf("iteration# %d | coord1 = %f coord2 = %f \n", i, &coordinates[i-1], &coordinates[i]);

收件人:

printf("iteration# %d | coord1 = %f coord2 = %f \n", i, coordinates[i-1], coordinates[i]);

【讨论】:

  • 感谢成功,我不敢相信我花了这么多时间在这么简单的事情上。
【解决方案2】:

第一个问题:

 while (fscanf(fp,"%f %f", &coordinates[i], &coordinates[i++]) > 1)

您正在尝试在&amp;coordinates[i] 中使用i 的值并在&amp;coordinates[i++] 中修改它,而无需插入序列点。这样做的行为是undefined,很可能不会做你想做的事。使用&amp;coordinates[i+1] 作为第二个参数。请注意,这意味着您必须在循环中使用i += 2 或类似名称更新i。请注意,保证&amp;coordinates[i]&amp;coordinates[i++] 之前被评估。

第二个问题:

printf("%f\n", &coordinates[i]);

再次,您调用了未定义的行为;你告诉printf 期待float 类型的值,但你传递的是float * 类型的值。丢失&amp;scanfprintf 在这方面是不对称的。

令人头疼的:

您知道每行将有 2 个值,但您从 5 开始数组大小(而不是 4、6 或 8)。您允许调整数组的大小(正确地,我可能会添加),但是您为打印循环硬编码了 8 的大小,而不是使用实际读取的项目数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 2016-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多