2012-06-28 24 views
0

我有數據的多個TEXTFILES如下讀取科學格式號碼℃。這兩列數據由製表符分隔。我正在試圖將這個數據文件讀入程序中作進一步處理。這是我寫的代碼如下:問題使用的fscanf()

#include <stdio.h> 
#include <stdlib.h> 

float **make_array(int size); //function to make 2D array 

int main(int argc, char **argv) 
{ 
     FILE *infile; 
     infile=fopen(argv[1], "r"); 

//count number of lines in file 
     char c; 
     int i=0, numlines=0; 
     while((c=fgetc(infile))!=EOF) 
       if(c == '\n') numlines++; 

     printf("numlines: %d\n", numlines); 

     float **entry = make_array(numlines); 

//read inputfile 
     for(i=0; i< numlines; i++) 
       fscanf(infile, " %G\t%G", &entry[0][i], &entry[1][i]); 
//verify read values 
     printf("\n"); 
     for(i=0; i<numlines; i++) 
       printf("%E\t%E\n", entry[0][i], entry[1][i]); 

//clean up before exiting 
     free(entry[0]); 
     free(entry[1]); 
     free(entry); 
     fclose(infile); 
return 0; 
} 


//create a 2D array of 2 by {size} 
float **make_array(int size){ 
     int i; 
     float **entry = malloc(2*sizeof(float *)); 
     if(entry==NULL) exit(1); 
     entry[0] = malloc(size*sizeof(float *)); 
     for(i=0;i<size;i++) entry[0][i] == 0.0; 
     entry[1] = malloc(size*sizeof(float *)); 
     for(i=0;i<size;i++) entry[1][i] == 0.0; 

return entry; 
} 

當我編譯並運行程序,它打印出的文件中正確的行數,但printf語句來驗證讀入陣列entry只是打印數據出全零,如下圖所示:

numlines: 252 

0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 
0.000000E+00 0.000000E+00 

我嘗試了不同的格式說明fscanf%g,%e,%f,%G etc但他們都給予同樣的結果。另外,我正在使用Ubuntu 12.04和GCC 4.6。任何指向什麼是錯誤的指針將不勝感激。

Khadija。

+0

你調試了嗎?爲什麼使用「%G \ t%G」你確定在中間有一個'\ t'字符 –

回答

4

你最初的循環:

while((c=fgetc(infile))!=EOF) 
    if(c == '\n') numlines++; 

讀取整個輸入文件(確定數組的大小)。完成之後,您撥打fscanf的電話都將失敗,因爲您已經在文件末尾。

假設輸入文件是可搜索的(應該是它是磁盤文件),您可以使用rewind()fseek()返回到開頭並再次閱讀。

順便說一句,你的%G%E格式說明符的使用是有效的,但%g%e是比較常見的(而且應該以完全相同的方式工作)。

在參考argv[1]之前,您應該確實檢查argc的值;如果調用時沒有命令行參數,程序可能會炸燬。您還應該檢查fopen()是否成功,並且fscanf()返回2表示它已成功讀取兩個數據項。

+0

非常感謝你的幫助。該程序現在正確讀取數據。也感謝你提供關於檢查程序參數的建議。我已經添加了。 – Khadija

1

那麼,問題是:

while((c=fgetc(infile))!=EOF) 
      if(c == '\n') numlines++; 

後您執行while循環,你的FILE *在EOF指指點點,所以當你到達:

for(i=0; i< numlines; i++) 
      fscanf(infile, " %G\t%G", &entry[0][i], &entry[1][i]); 

每一個的fscanf返回EOF而且你根本不掃描這些值。

0

基思指出問題,但一些其他的事情你應該想想:

  • 檢查的fscanf的結果;它會返回成功轉換和分配的次數。如果返回小於2,那麼你沒有正確讀取你的數據;

  • 您在使用malloc調用entry[0]entry[1]時使用了錯誤的數據類型;你應該使用sizeof (float),而不是sizeof (float *)。你可以通過編寫entry[0] = malloc(sizeof *entry[0] * size);來清理東西 - 這樣你就不會有這些類型的不匹配。

  • 兩次讀取文件效率低下且不必要;由於您無論如何都在動態分配陣列,因此您可以在讀取文件時使用realloc來擴大entry[0]entry[1]的大小。

+0

感謝您的意見。我添加了'fscanf'返回的檢查參數作爲安全措施。我不太確定使用'realloc',這就是爲什麼我沒有使用它。我將在數據讀入時查看如何調整數組的大小。 – Khadija