2011-08-14 148 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格式說明符有點棘手,但代碼需要知道在下一個週期中何處恢復讀取緩衝區。