这是我的C编程课程的家庭作业。
我得到一个文本文件,有两个数据列;第一列是age
;第二列是avgprice
。我能够很好地阅读和打印这些值。但是,出于某种原因,age
和avgprice
会在输出中翻转。我不知道为什么。
这是代码
#include "stdafx.h"
#include <stdio.h>
int main() {
double age, avgprice; //age = 1st column, avgprice = 2nd column
FILE *corolla; //ptr for file
char eof; //needed for end of file check
corolla = fopen("C:/Users/Nate/Downloads/DataFiles/corolla.txt", "r");
if (corolla == NULL) { //makes sure the file exists
printf("File does not exist!\n");
return 0; //prevents crashing
}
else {
printf("Age \t\t Average Price\n"); //header for data when printed
/*prints values until we're at the end of the file*/
while (fscanf(corolla, "%c", &eof) != EOF) {
fscanf(corolla, "%lf %lf", &age, &avgprice); //scans in data from file
printf("%.1f \t\t $%.2f\n", age, avgprice); //prints data from file
}
}
fclose(corolla); //closes file
return 0;
}
这是输出的样子
这令我感到困惑,因为我使用这种确切的格式与其他数据文件做同样的事情 - 没有问题。由于某种原因,这个文件有困难。
这是我应该阅读的数据文件。我已将其上传到我的Dropbox,您可以根据需要检查格式。 Corolla.txt
答案 0 :(得分:1)
您的输入文件使用基于行的格式。 fscanf
按块读取输入块。块通常是由空白隔开的东西,可以是空格,制表符甚至是新行。因此fscanf
不适合读取基于行的格式。
在我看来,最好分两步读取输入:首先,用fgets
读取一行,然后用sscanf
读取该行的数据。例如:
#include <stdlib.h>
#include <stdio.h>
int main()
{
FILE *f;
int line = 0;
f = fopen("kk", "r");
if (f == NULL) {
printf("File does not exist!\n");
return 0;
}
printf("%20s%20s\n", "age", "avg. price ($)");
for (;;) {
char buffer[80];
int age, price;
if (fgets(buffer, sizeof(buffer), f) == NULL) break;
line++;
if (sscanf(buffer, "%d %d", &age, &price) < 2) {
printf("(Skipping bad input in line %d).\n", line);
} else {
printf("%20d%20d\n", age, price);
}
}
fclose(f);
return 0;
}
这也为您提供了一种低级错误报告。
此外,通常无需对EOF
进行额外检查。当到达文件末尾时,文件输入函数返回特殊值。 fscanf
和getc
返回EOF
; fgets
返回NULL
。根据这些返回值停止阅读通常总是更好。
在你的情况下,fscanf("%c", &oef)
会占用文件中的第一个字符,即数字1.幸运的是,之后它只会以换行符为主,因此您的输入不会变得更糟。 (但要将扫描格式更改为"%lf %lf "
,以便大幅降价。)
答案 1 :(得分:1)
这一行:
while (fscanf(corolla, "%c", &eof) != EOF)
从文件中读取一个字符。文件中的第一个字符为1
,因此它将1
读入eof
。
你的下一行是:
fscanf(corolla, "%lf %lf", &age, &avgprice);
按顺序读取文件中的下两个条目,即13990
和2
。因此,第一个年龄为13990
,第一个平均价格为2
。
之后,文件指针现在指向2
之后的空白区域。你去的时候:
fscanf(corolla, "%c", &eof)
它将空格读入eof
。
然后当你到达:
fscanf(corolla, "%lf %lf", &age, &avgprice);
它分别读取接下来的两个值13495和3。等等。
要解决此问题,您应该停止fscanf(corolla, "%c", &eof)
。我不知道你期望这完全做什么,但它不测试你是否在文件的末尾。相反,它会读取一个字符,忽略该字符,并检查fscanf
的返回值。
修复您的代码:
while (2 == fscanf(corolla, "%lf %lf", &age, &avgprice))
{
printf("%.1f \t\t $%.2f\n", age, avgprice); //prints data from file
}
fscanf
的返回值是成功读取的项目数(如果成功)。当它返回2
以外的其他内容时,您知道必须已经到达文件的末尾。