使用 fscanf *after* fgetc 问题

Using fscanf *after* fgetc issue

在 C 中,有很多帖子涉及在 fscanf 之后使用 fgetc,处理额外的 \n,但是当我以相反的顺序使用它们时,我看到了另一个问题; fscanf 之后 fgetc.

fgetc 之后使用 fscanf 时,如果我只是省略 fgetc,我会得到一个不同的 fscanf 结果(在示例脚本中,只是硬编码num=1000 并使用 fgetc).

注释掉该块

如果我将文件内容重写到 myFile 变量,我可以复制这个正确的 fscanf-结果,同时仍然使用 fgetc,如下面的脚本所示。删除此行会产生不同的不正确 fscanf-result.

首先使用 fgetc 时导致 fscanf 结果不同的原因是什么,我该如何解决这个问题?

/* First read tab-delimited 4-digit int data from a text file,
 * parsing into an array of the correct size num, then compute
 * the mean of the array while avoiding overflow. */

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

int main(){
    FILE *myFile;
    myFile = fopen("int_values.txt", "r");

    int c=0, i=0;
    float mean = 0.0;

    // Identifying there are 1000 values in the tab-delimited file.
    // Using fgetc
    int num = 1;
    while ((c=fgetc(myFile)) != EOF ){
        if (c == '\t')
            ++num;
    }

    int arr[num]; // Array of correct size for all values from file.

    // Redeclaring since fgetc seems to break fscanf
    myFile = fopen("int_values.txt", "r");

    // Read and store each value from file to array.
    for (i=0; i<num; i++){
        fscanf(myFile, "%d ", &arr[i]);
    }
    // Compute average cumulatively to avoid overflow.
    mean = arr[0]
    for (i=1; i<num; i++){
        //printf("In the %dth place, arr has value %d.\n", i, arr[i]);
        mean *= (float)i / (float)(i+1);
        mean += arr[i] / (float)(i+1);
    }
    
    fclose(myFile);

    printf("The overall mean of the %d values in the file is %f.\n\n", num, mean);
    return 0;
}

Identifying there are 1000 values in the tab-delimited file.

不计算制表符。相反,阅读 ints。选项卡的数量很容易与 int.

的数量不正确相关

int 求和为 long long 以避免溢出。使用 double 进行通用浮点运算。

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

int main(void) {
  FILE *myFile = fopen("seal_weights.txt", "r");
  if (myFile) {
    int num = 0;
    long long sum = 0;
    int value;
    // return 1 on success, EOF on end-of-file, else 0 on non-numeric input
    while (fscanf(myFile, "%d", &value) == 1) {
      sum += value;
      num++;
    }
    double mean = num ? (double) sum / num : 0.0;
    printf("The overall mean of the %d values in the file is %f.\n\n", num,
        mean);

    // read in again and save values if truly desired.
    // This step not needed to compute average.
    rewind(myFile);
    int i;
    int arr[num];
    for (i = 0; i < num; i++) {
      if (fscanf(myFile, "%d", &arr[i]) != 1) {
        break;
      }
    }
    // Use arr[] in some way.

    fclose(myFile);
  }
  return 0;
}