使用 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.
不计算制表符。相反,阅读 int
s。选项卡的数量很容易与 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;
}
在 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.
不计算制表符。相反,阅读 int
s。选项卡的数量很容易与 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;
}