我正在尝试从包含此文本的文件中读取:
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。
开头答案 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