扫描随机数量的浮点数直到C中的新行

时间:2014-03-30 21:18:36

标签: c scanf

我正在尝试从包含此文本的文件中读取:

  

f 502 601 596 465 464
  f 597 599 600 598
  f 602 591 596 601
  f 588 565 548 260 62 61 595
  f 583 595 61 558 561
  f 237 241 471

在每一行上都有一个f后跟随机数量的浮点数。我希望能够在f之后取数字并将它们存储在一系列花车结构中。我写的代码将解析文本文件,如果每行有三个浮点数,但现在我被指示如果有一个随机数量的浮点数(最多13个浮点数)。基本上我现在在每一行上有三个浮点数的代码如下:

struct faces {
  float p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12;
}

struct faces eFace[100];

FILE *fp;
char buff[128];
int fCount = 0;
fp = fopen("text.txt", "r");

if (fp == NULL)
    printf("Can't open file");
else {
    while (fgets(buff, sizeof(buff), fp) != NULL) {
        if (buff[0] == 'f') {
            sscanf(buff, "f %f %f %f", &eFace[fCount].p1, &eFace[fCount].p2, &eFace[fCount].p3);
            fCount++;
        }
    }
}
fclose(fp);

}

修改我的代码的最佳方法是什么,以便在" f"之后需要每个浮点数(最多13个浮点数)。直到换行并将它们存储在我制作的结构数组中?我感谢您的帮助,如果您需要更多信息,请告诉我们!

注意:我总是要检查该行是否以f。

开头

1 个答案:

答案 0 :(得分:2)

由于你有浮点数的上限,使用它,但不要硬编码13。

扫描文件两次以确定行数。

使用fgets()读取每一行。

使用sscanf()strtod()阅读每个号码。务必执行错误检查。

未经测试的代码如下:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#define faces_N 13

typedef struct faces {
  float p[faces_N];
} faces_T;

void foo(void) {
  faces_T *eFace = NULL;
  size_t Lines = 0;

  FILE *fp;
  fp = fopen("text.txt", "r");
  if (fp == NULL)
    printf("Can't open file");
  else {
    char buff[2*(faces_N*(FLT_DIG + 10) + 1 + 1)];
    while (fgets(buff, sizeof(buff), fp) != NULL)
      Lines++;
    rewind(fp);
    eFace = malloc(Lines * sizeof(*eFace));
    assert(eFace);

    for (size_t l = 0; l < Lines; l++) {
      if (fgets(buff, sizeof(buff), fp) != NULL)
        Handle_IOError();
      if (buff[0] != 'f')
        Handle_FormatError();
      size_t f;
      char *p = &buff[1];

      for (f = 0; f < faces_N; f++) {
        int n;
        if (sscanf(p, "%f%n", &eFace[l].p[f], &n) != 1)
          break;
        p += n;
      }
      // TBD what to do with other
      for (; f < faces_N; f++) {
        eFace[l].p[f] = 0.0;  // Or maybe NaN or save count in eFace
      }
    }
    fclose(fp);

    // do whatever with eFaces;

  }
  free(eFaces);
}

buff的大小值得商榷。我喜欢最大预期大小的2倍,如果缓冲区已满,则会抛出错误。

char所期望的float个数应该能够区分所有float。通过" -D.DDDDDDddde-dd"估算1 (space) + 1 (sign) + 1 (.) + FLT_DIG + 3 (see link) + 4 (exponent)。有关打印精度的讨论,请参阅链接:width specifier to maintain precision of floating-point value