0

ユーザーが入力したテキスト ファイルを取得し、最大数、最小数、数値の平均、および数値の標準偏差を返すプログラムを作成しようとしています。入力したテキスト ファイルは次のようにフォーマットされています (最初の数字は「N」、つまり数字の総数、2 行目はすべての数字のリストです)。

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()成功したことを確認しません。おそらく整数値であるべきものを に読み込むのも奇妙ですdoubleが、使用されている表記法は機能します。
  5. 特に…の場合は、そのように使用しないでくださいfeof()。</li>
  6. 2 番目が成功したことを確認しない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 であると報告されます。if (i == 0 || num < min) min = num;すべての数値が正の場合、最小値が 0 であると報告します。これを修正するのは少し面倒ですが、などを使用できます。


リンクの問題

リンクの問題 (未定義の への参照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ファイルの先頭に。

  • floatで aを読み取りたい場合は、 (整数を読み取る)ではなく、書式指定子scanfを使用する必要があります。%f%d
  • fopen呼び出しで、 を囲む引用符を削除しますargv[1]。そうしないと、その名前のファイルが検索されます。
于 2013-10-31T01:48:34.060 に答える