在 C 语言中以不同的目录打开文件会导致分段错误?



我正在尝试从与Unix平台上当前目录不同的文本文件"P1-Data"中读取,并创建一个GPA数组以使用C语言计算平均GPA。

这是名为"P1-Data"的文本文件:

Mark Bhatia 852600012  3.23
Larry Burch 123236399  2.94
Howard Huge 234123456 3.00
# Andrew Jackson 123321123 4.00
Lee David 666656666 3.02
Norden Bruce 432156978 3.75
Price Jones 121256435 2.75
Rountree Travis 123123132 2.89
Volek Volek 101100100 3.05
# Fine Students 000000121 4.0
John Bhatia 952600012  3.93
Jangla House 123457890 2.03 
# Tee David 666656667 3.42
# Moriarty Hodges 898888999 2.04
Wonder Druce 332156978 3.78
Price Hones 121256435 2.75
Flattree Travis 123123134 3.95
Drew Pete 101100101 3.05

这位于目录:home/.../class1/.../.../P1-DATA

这是名为"stage1.c"的 C 代码,它给了我错误(用记事本++编写):

#include <stdio.h>
#include <math.h>
int main(int argc, char* argv[]){
int i = 0;
float sum = 0.00, n = 0.00, avg = 0.00;
FILE *fin;
fin = fopen("P1-DATA", "r");
// Keep reading in integers (which are placed into "n") until end of file (EOF)
while(fscanf(fin, "%lf", &n) != EOF){
// Add number to sum
sum += n;
// Increment counter for number of numbers read
i++;
// Average is sum of numbers divided by numbers read
avg = (sum / i);
}
// After the loop is done, show the average
printf("The average is %lf.n", avg);
fclose(fin);
return 0;
}

这位于目录:home/.../class2/s/name/.../stage.c (要点不同目录)

我还注意到,我在尝试打开的文件名中输入的内容并不重要。我仍然遇到分段错误。所以我想我在那之前错过了一些东西。也许我需要切换到"P1-DATA"文件所在的目录?㞖。。我不确定如何在 C 中做到这一点。 任何帮助将不胜感激。 另外,我的日程安排有点紧。这只是我需要做的第一部分。提前感谢!

你对这一行有一个严重的问题:

while(fscanf(fin, "%lf", &n) != EOF){

因为nfloat而不是double.因为您尝试将 64 位double写入 32 位float,所以所有投注都已关闭(未定义的行为)。

该标准指出,l前缀"指定......以下aAeEfFgG转换说明符适用于类型指针指向double的参数。

对于float,您应该只使用%f。或者你可以把所有的浮点类型都变成double- 我很少再使用float类型了。


此外,检查使用它们来指示错误的函数的返回值(以及errno)被认为是一种很好的做法。如果fopen失败,则fin将设置为NULL,然后尝试使用它来读取数据将是一个坏主意。像这样:

#include <errno.h>
:
fin = fopen("P1-DATA", "r");
if (fin == NULL) {
printf ("Error %d opening input filen", errno);
exit (1);
}

会的。有更友好的方法可以做到这一点,但这至少会让您知道是否发生了错误以及错误是什么。


根据您的评论,这为您提供了错误代码 2(ENOENT),这是因为该文件不存在。运行程序时,您需要位于数据文件所在的目录中,或者在fopen中提供它的完整路径名。

不是在代码中指定数据文件的名称,而是 可以改为将其指定为命令行参数。

#include <err.h>
#include <stdio.h>
if (argv[1] == NULL)
err(1, "usage: %s datafile", argv[0]);
if ((fin = fopen(argv[1], "r")) == NULL)
err(1, "Could not open "%s"", argv[1]);

(请注意上面fopen()对返回值的检查。

然后,您可以使用数据文件的路径作为 命令行参数:

% ./a.out /path/to/the/data/file

另请注意,您的数据文件似乎比 浮点数的简单列表。 尝试解析该数据 使用简单的"%f"格式字符串不太可能起作用。

相关内容

  • 没有找到相关文章

最新更新