0

我正在尝试编写一个程序,该程序采用用户输入的文本文件并返回最大数、最小数、数字的平均值和数字的标准偏差。我们输入的文本文件格式如下(第一个数字是“N”,或数字总数,第二行是所有数字的列表):

5

4.34 23.4 18.92 -78.3 17.9

到目前为止,这是我的代码

int main(int argc, char*argv[])
{
    double average, num = 0, min = 0, max = 0, sum = 0, N, std_dev, sum_sqs;
    FILE * pFile;
    pFile = fopen("argv[1]", "r");
    fscanf(pFile, "%lf", &N);

    while(!feof(pFile))
    {
            fscanf(pFile, "%d", &num);
            if (num < min)
                    min = num;
            if (num > max)
                    max = num;
            sum += num;
            sum_sqs += (num*num);
    }
    average = sum/N;
    std_dev = sqrt((sum_sqs/N)-(average*average));

    printf("Smallest: %.2lf\n", min);
    printf("Largest: %.2lf\n", max);
    printf("Average: %.2lf\n)", average);
    printf("Standard deviation: %.3lf\n", std_dev);
return(0);
}

目前,编译器不允许我通过关于未定义的 sqrt 引用的错误,我无法弄清楚出了什么问题。提前感谢所有花时间回复的人!我真的很感激任何帮助,我仍然掌握 C 的窍门。如果我的代码没有按照我的意图做,请不要犹豫,纠正我!

将混乱的部分更新到下面。尽管哈哈 pFile = fopen(argv[1], "r"); 仍然不确定我到底在做什么 fscanf(pFile, "%lf", &N);

    if (fscanf(pFile, "%lf", &N) == 1)
    {
            for (int i = 0; i < N; i++)
            {
            if (fscanf(pFile, "%lf", &num) == 1)
                    if (num < min)
                            min = num;
                    if (num > max)
                            max = num;
                    sum += num;
                    sum_sqs += (num*num);
    }
    average = sum/N;
    std_dev = sqrt((sum_sqs/N)-(average*average));
4

2 回答 2

6

分析

这几行有很多问题:

pFile = fopen("argv[1]", "r");
fscanf(pFile, "%lf", &N);

while(!feof(pFile))
{
        fscanf(pFile, "%d", &num);
  1. 您可能想打开由 指定的文件argv[1],而不是名为 的文件argv[1]。删除引号。
  2. 你没有检查你是否被传递了一个论点。
  3. 你没有检查fopen()成功,所以你可能在你的第一个fscanf().
  4. 你没有检查fscanf()成功。将可能应该是整数值的内容读入 a 也很奇怪double,但使用的符号将起作用。
  5. 你不应该那样使用feof(),尤其是如果……</li>
  6. 您没有检查第二个是否fscanf()成功,它不会正常工作(但可能不会报告问题),因为......</li>
  7. 您正在尝试将整数 ( %d) 读入double.

所以,你应该写:

if (argc <= 1)
    …report error and exit…(or use pFile = stdin)…
FILE *pFile = fopen(argv[1], "r");
if (pFile == 0)
    …report error and exit…
if (fscanf(pFile, "%lf", &N) == 1)
{
    for (int i = 0; i < N; i++)
    {
        if (fscanf(pFile, "%lF", &num) != 1)
            …report error, close file, and exit…
        …as before…more or less…subject to fixing any as yet undiagnosed errors…
    }
}
fclose(pFile);

顺便说一句,你在开始添加之前忘记设置sum_sqs为零,所以你不会知道你得到了什么值。此外,如果所有数字均为负数,您将报告最大值为 0;如果所有数字都是正数,您将报告最小值为 0。修复它有点繁琐,但您可以使用if (i == 0 || num < min) min = num;etc.


链接问题

您的链接问题(对 的未定义引用sqrt())表明您在需要链接数学库的系统上运行;这通常-lm位于链接命令行的末尾。


合成

#include <stdio.h>
#include <math.h>

int main(int argc, char*argv[])
{
    double average, num = 0, min = 0, max = 0, sum = 0, N, std_dev, sum_sqs = 0.0;

    if (argc <= 1)
    {
        fprintf(stderr, "Usage: %s file\n", argv[0]);
        return 1;
    }

    FILE *pFile = fopen(argv[1], "r");
    if (pFile == 0)
    {
        fprintf(stderr, "%s: failed to open file %s\n", argv[0], argv[1]);
        return 1;
    }
    if (fscanf(pFile, "%lf", &N) == 1)
    {
        for (int i = 0; i < N; i++)
        {
            if (fscanf(pFile, "%lF", &num) != 1)
            {
                fprintf(stderr, "%s: failed to read number\n", argv[0]);
                return 1;
            }

            if (num < min || i == 0)
                min = num;
            if (num > max || i == 0)
                max = num;
            sum += num;
            sum_sqs += (num*num);
        }
    }

    fclose(pFile);
    average = sum/N;
    std_dev = sqrt((sum_sqs/N)-(average*average));

    printf("Smallest: %7.2lf\n", min);
    printf("Largest: %7.2lf\n", max);
    printf("Average: %7.2lf\n", average);
    printf("Standard deviation: %7.3lf\n", std_dev);
    return(0);
}

结果

给定数据文件data

5    
4.34 23.4 18.92 -78.3 17.9

运行程序的结果是:

Smallest:  -78.30
Largest:   23.40
Average:   -2.75
Standard deviation:  38.309

这些值大多看起来是合理的;我计算的标准差为 42.83(完全使用不同的工具)。差异在于样本标准偏差和总体标准偏差(一个因子 √1.25)——所以你的值在你计算的时候是可以的。

# Count    = 5
# Sum(x1)  = -1.374000e+01
# Sum(x2)  =  7.375662e+03
# Mean     = -2.748000e+00
# Std Dev  =  4.283078e+01
# Variance =  1.834476e+03
# Min      = -7.830000e+01
# Max      =  2.340000e+01

所以,代码对我有用。你得到什么结果?

于 2013-10-31T02:28:08.337 回答
0

如果你想要这个sqrt功能,你需要添加

#include <math.h>

到 C 文件的顶部。

  • 如果你想读 a floatwith scanf,你应该使用%f格式说明符,而不是%d(它将读取一个整数)。
  • 在您的fopen通话中,删除 周围的引号argv[1],否则它将查找具有该名称的文件。
于 2013-10-31T01:48:34.060 回答