簡體   English   中英

使用 fscanf 時停止 while 循環?

[英]Stopping a while loop when using fscanf?

我遇到了這個問題:我有一個帶有空格分隔數據點的.txt 文件,我正在使用 fscanf 獲取這些數據點並將它們存儲到一個浮點數組中。 問題是我也在嘗試處理錯誤的輸入(例如,12.3 有效但 a.2、e、ef、a.2 等無效)所以我設置了以下內容:

float data[20];
int count = 0;
FILE *fp;
fp = fopen(argv[1], "r");
while ((count < 20)) {
    if fscanf(fp, "%f", &data[count]);
    else {
        data[count] = -1000;
    }
}

目前,我將其硬編碼為以 20 個循環結束。 但我需要它在文件中數據的末尾結束,它有 11 個值。 目前它正確加載這些值,但繼續循環。 我嘗試了 EOF 實現,但遇到了錯誤數據處理的問題。

我發現閱讀fscanf文檔總是有幫助的。 它對我說的是它返回三個值之一,(在你的情況下。)如果一個人的程序格式正確,就必須考慮所有這三個值。

返回 意義
1個 解析器能夠在數據類型的限制內合理地解釋和存儲給定的一個值。
0 給定格式字符串,這些字節沒有意義。
EOF 由於某些其他原因無法讀取該字符; 它可能是文件的結尾。
  • 為了避免重復錯誤系統,也許#include <errno.h>會有效嗎?
  • 我喜歡把相關數據放在一個結構中, struct { size_t count; double data[20]; } join; struct { size_t count; double data[20]; } join; 可以通過const size_t join_max = sizeof join.data / sizeof *join.data; .
  • 小心測試有 20 個浮點數的邊緣情況。
  • fopen是一個額外的復雜性,它不應該存在於簡單的命令行程序中, shell 通常可以做得更好, ./a.out < data
  • 請參閱有關float vs double的討論。

在您的情況下,閱讀一個double可能看起來像:

switch(scanf("%lf", &lf)) {
case EOF: if(feof(stdin)) goto eof; else goto catch;
case 0: errno = EILSEQ; goto catch;
case 1:
    if(join.count < join_max) join.data[join.count++] = lf;
    else { errno = ERANGE; goto catch; }
    break;
}

--

“這些 goto 怎么了?”

至少必須考慮這些條件:

  • 結果添加了,再試一次。
  • 文件完成,成功。
  • 讀取錯誤,語法錯誤,或者數組中沒有空間容納更多; (根據應用程序,我認為這些可以組合在一起。)

如果有一個像異常這樣的標准帶外機制,那就更容易了。 我可以告訴你我的代碼是如何運行的,但這只是一個快速編造的例子,不一定是好的設計:

{
    int success = EXIT_FAILURE;
    (loop)
        (scanf)
eof:
    (print)
    { success = EXIT_SUCCESS; goto finally; }
catch:
    sprintf(reason, "Data %lu", join.count);
    perror(reason);
finally:
    return success;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM