2011-08-14 110 views
0

这个函数应该得到一个向量文件。第一行 包含维度。所有其他线路的形式为 “P:3,5,2”。字母是P或N,数字是坐标。 该函数在每次调用时读取一行,并将P/N字符和坐标保存为double数组。读取c文件时出现问题

void readSamplesFile(FILE *sample_p, double result[]) 
{ 
    if (dimension == 0) 
    { 
    fscanf(sample_p,"%lf",&dimension); 
    } 
    printf("dimentions: %lf\n",dimension); 
    printf("LINE \n"); 
    int index; 
    for (index = 0; index<dimension; index++) 
    { 
     printf("%d",index); 
     fscanf(sample_p,"%lf%*[:,]",&result[index]); 
     printf("%lf",result[index]); 
    } 
}  

当我运行它我得到一个无限循环。尺寸被正确地读取,但它打印的

LINE 
00.00000010.000000dimentions: 2.000000 

无止境地。任何想法为什么? 希望我是清楚的

编辑: 我已经添加了调用函数:

void fillArray(FILE *sample_p,FILE *separators_p){ 
    double coordinates[MAX_DIMENSION]; 
    while (!feof(sample_p)){ 
     readSamplesFile(sample_p,coordinates); 
    } 
} 

附: fscanf设置为阅读:和,但忽略它们。

+3

单独考虑,此代码不会编译。 “维度”及其堂兄“维度”的定义是什么(迫切需要一个更好的变量名称)? – phihag

+0

它是同一个变量,我在这里更正了我的拼写,没有注意到最后一个。但在我的代码中它是同一个。维度只是一个双倍 – yotamoo

+0

检查fscanf的返回值 –

回答

1

'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格式说明符有点棘手,但代码需要知道在下一个周期中何处恢复读取缓冲区。