'P'和'N'都不是有效的双倍数,也不是':'或',',所以fscanf()
失败。您应该始终检查fscanf()
的返回值。
我们也可以辩论,您是否更愿意使用fgets()
来读取一行,sscanf()
来解析它。这样做可以避免一些问题;这是我自动编写代码的方式。
此代码似乎对输入文件的工作:
3
P:3,5,2
N:21.12,2.345e6,1.9132e-34
产生输出:
dimension: 3.000000
LINE: P:3,5,2
P:offset=2:0=3(2):1=5(4):2=2(6):
LINE: N:21.12,2.345e6,1.9132e-34
N:offset=2:0=21.12(2):1=2.345e+06(8):2=1.9132e-34(16):
我仍然不热衷于(MIS)使用浮动点dimension
,但它的工作原理。
#include <stdio.h>
enum { MAX_DIMENSION = 6 };
enum { MAX_BUFFSIZE = 4096 };
static double dimension = 0.0;
static int get_dimension(FILE *fin)
{
char buffer[MAX_BUFFSIZE];
if (fgets(buffer, sizeof(buffer), fin) == 0)
return -1;
if (sscanf(buffer, "%lf", &dimension) != 1)
return -1;
printf("dimension: %lf\n", dimension);
return 0;
}
static int readSamplesFile(FILE *sample_p, double result[])
{
char buffer[MAX_BUFFSIZE];
if (fgets(buffer, sizeof(buffer), sample_p) == 0)
return -1;
printf("LINE: %s", buffer);
char c;
int offset;
if (sscanf(buffer, " %c:%n", &c, &offset) != 1)
return -1;
printf("%c:", c);
printf("offset=%d:", offset);
for (int index = 0; index < dimension; index++)
{
int newoff;
if (sscanf(&buffer[offset], "%lf%*[:,]%n", &result[index], &newoff) < 1)
return -1;
printf("%d=%g(%d):", index, result[index], offset);
offset += newoff;
}
putchar('\n');
return 0;
}
static void fillArray(FILE *sample_p)
{
double coordinates[MAX_DIMENSION];
while (readSamplesFile(sample_p, coordinates) == 0)
;
}
int main(void)
{
if (get_dimension(stdin) == 0)
fillArray(stdin);
return 0;
}
注意,fillArray()
功能,如写的,不与数据线做任何事情。没有检查指定的尺寸是正数并且不大于MAX_DIMENSION
(这将在get_dimension()
中进行)。将get_dimension()
分隔成一个单独的功能比将其隐藏在readSampleFile()
中感觉更清洁。有一个说法,readSampleFile()
应该重命名为readSampleLine()
,因为它一次只处理一行,而不是一次处理整个文件。
使用%n
格式说明符有点棘手,但代码需要知道在下一个周期中何处恢复读取缓冲区。
单独考虑,此代码不会编译。 “维度”及其堂兄“维度”的定义是什么(迫切需要一个更好的变量名称)? – phihag
它是同一个变量,我在这里更正了我的拼写,没有注意到最后一个。但在我的代码中它是同一个。维度只是一个双倍 – yotamoo
检查fscanf的返回值 –