2013-03-13 131 views
2

我正在編寫一個程序,使用C只是從包含大約500個浮點數(例如54.54)的輸入文件中查找最大和最小值。我可以讓程序運行,但輸出說我的最小值是0,最大值是54.88,這是文件中的第一個數字。 這是我到目前爲止。從C中的文件查找最大和最小浮點數

#include <stdio.h> 

int main(int argc, const char * argv[]) 
{ 

    FILE * fp; 

    fp=fopen("file.txt","r"); 
    if (fp==NULL) 
    { 
     printf("Failed to open"); 
    } 

    float i; 
    float min ; 
    float max ; 

    { 
     fscanf(fp, "%f", &i); 

     if (i < min) 
      min = i; 
     if (i > max) 
      max = i; 
     } 
    printf("Data range is: %f %f \n", min, max); 
    return 0; 
} 
+3

也許你應該考慮循環遍歷文件,而不是隻讀第一個數字?可能用一個while循環直到文件結束? – 2013-03-13 04:42:22

+0

@殭屍:你的評論是不明確的。這可能意味着「沒有;事實上,浮動數據被默認初始化爲零」,或者它可能意味着「浮動數據庫默認從不初始化爲零」。後者對於自動和動態分配的「浮點」變量更爲準確;前者更接近靜態和外部變量的準確性。我懷疑已經對評論做了一些清理工作,所以最好刪除你的評論(並且讓我知道刪除這個評論)。 – 2013-03-13 05:30:06

+0

@JonathanLeffler我的意思是花車總是0初始化。 ACB在發佈該評論時發表了評論 - 這表示他必須初始化浮點值,而我說不 - 不需要:-) – 2013-03-13 05:31:32

回答

0

您沒有讀取文件中所有數字的循環。你得到的只是第一個。

+0

我不知道該怎麼把for循環的第二個條件? mark是for(i = 0; i <?; i ++) – mogley 2013-03-13 05:05:08

0

如果你知道每行只有一個雙精度值,你可以這樣做。這可能不是最優雅的,但在我的腦海中編譯它似乎可以完成工作。

(我沒有bug的測試此代碼,也我不知道這是最大和最小的雙重價值權宏)

char buf[10]; /* as big as the biggest number */ 
char c; 
int i = 0; 
double d, dmax = -INFINITY, dmin = INFINITY; 

while ((c = getc(fp)) != EOF) { 
    if (c != '\n') 
     buf[i++] = c; 
    else { 
     buf[i] = '\0'; 
     d = atof(buf); 
     if (d > dmax) dmax = d; 
     if (d < dmin) dmin = d; 
     i = 0; 
    } 
} 
+0

在C99中,''定義了INFINITY,如果FPU支持它,這將是一個正無窮大,所以你可能很好走。另一個技巧(避免無限)是讀取第一個值並將其分配給'dmax'和'dmin';之後,將新值與這些保存的值進行比較。兩者工作得很好;如果至少有一個數字要閱讀,它們是等效的。當然,你的代碼容易受到緩衝區溢出的影響;如果我輸入3.14159265389,那麼我寫的超出了'buf'的範圍。該緩衝區應該更大。你可以考慮'scanf()'或者使用'fgets()'和'sscanf()'。 – 2013-03-13 05:35:51

+0

是的,我對緩衝區的大小有一個(保守的)猜測,但實現者應該能夠相應地修復它。 – 2013-03-13 05:39:59

+0

嗯......有趣;我的保守猜測版本將從256開始,並由2到4096的權力上升; (4096)就是我用來存儲一行的時候,當我不能檢查溢出的時候(但是我使用'fgets()'來讀取這行,避免了溢出;我通常不會花費時間來檢測該行的結尾沒有出現在前4095個字符中)。顯然,如果你的機器只有內存的KiB,那麼你擔心它;如果它有內存的MiB或GiB,則4096是小改動。 – 2013-03-13 05:48:07

1

最小/最大應被初始化爲適當的值。例如。

float inf = 1.0/0.0; // also in math.h as INFINITY? 
float max = -inf; 
float min = inf; 
float i; 

另一種選擇是將min和max初始化爲從文件讀取的第一個值。這是編碼循環的一種方式:

while (fscanf(fp, "%f", &i)==1) // 
{ 
    ... 
} 
+0

這裏的核心信息有點不足,但它是準確的,即使我對WhozCraig的回答發表了評論,也會給你加票。而你對另一個答案的評論也是針對目標的。做得好。 – 2013-03-13 06:11:35

1

該程序將符合該法案。

#include <stdio.h> 

int main() 
{ 
    float num; 
    float min = 999.99; /*Max value of number your file will not exceed*/ 
    float max = 0; 
    int i = 0; 

    FILE *fp; 
    fp = fopen("file.txt", "r"); 

    while(fscanf(fp,"%f",&num) == 1) 
    { 
      if (num < min) 
      min = num; 
      if (num > max) 
      max = num; 
    } 

    fclose(fp); 

    printf("Data range is: %f %f \n", min, max); 

    return 0; 
} 
+0

請不要使用'feof()'那樣的; C不是帕斯卡。另外,檢查從'fscanf()'返回的值:while(fscanf(fp,「%f,&float_var)== 1)'(假設'float float_var;')。注意這個問題有500個數字;但是,有趣的是,你的代碼不會崩潰和燒燬;這是因爲你將'i'設置爲0,並且你永遠不會增加它,所以你只能使用數組中的第零個元素,所以10太大了,在C中,常量通常寫在所有的大寫中:'enum {NUM_ELEMENTS = 500};',例如 – 2013-03-13 06:06:38

+0

@JonathanLeffler感謝您的更正(不知道'feof() ),我會立即調查並做出適當的修改 – 2013-03-13 06:12:38

+0

@JonathanLeffler,你說的對,使用數組毫無用處,它只需要一個變量,程序運行良好,但是我仍然需要找到一個合適的代替'feof ()',保持邏輯完整 – 2013-03-13 06:20:26

1

保持大部分代碼:

#include <stdio.h> 

int main(int argc, const char * argv[]) 
{ 
    float i=0, min=0, max=0; 
    FILE * fp fp=fopen("file.txt","r"); 
    if (fp==NULL) 
    { 
     perror("Failed to open file."); 
     return EXIT_FAILURE; 
    } 

    if (fscanf(fp,"%f", &i) == 1) 
    { 
     min = max = i; 
     while (fscanf(fp, "%f", &i) == 1) 
     { 
      if (i < min) 
       min = i; 
      else if (i > max) 
       max = i; 
     } 
    } 

    printf("Data range is: %f %f \n", min, max); 
    return 0; 
} 

對不起任何錯字。

+0

耶!一個可投票的答案! – 2013-03-13 06:07:47

+1

@JonathanLeffler Pfft。這是*殺死*我看這個線程= P – WhozCraig 2013-03-13 06:08:13