0

関数を使用してユーザー入力を検証しています。

これが私のコードです:

#include <stdio.h>

void get_income(double *pschool, double *pincome);
double get_double(void);

main()
{
    get_income(&pschool, pincome);
}

void get_income(double *pschool, double *pincome) {
    int tuition, supplies;

    printf("Enter tuition:");
    scanf("%d", &tuition);
    printf("Enter supplies:")
    scanf("%d", &supplies);

    *pSchool = tuition + supplies;
    return;
}

double get_double(void) {
    // validation code should go in here 
}

と のユーザーが指定した値を検証して、両方が 0 以上であり、空でないことをtuition確認する必要があります。supplies負の値や数字以外は受け付けません。

検証コードは関数内にある必要がありget_double、別の関数にあるものを検証する方法がわかりません。ガイダンスを探してください。

4

3 に答える 3

0

コードには、次のような多くの問題があります。

  • 関数をチェックしないscanf()とデータが見つかります
  • の誤った宣言main()
  • 未使用のポインタをに渡すget_income()
  • 機能のチェックからステータスを返さない
  • 入力されたデータについて報告しない
  • で変数を宣言しないmain()
  • 目的と一致しない関数名
  • 浮動小数点数に格納するための整数の読み取り

sscanf()「データを読み取らせる」よりも、「行を読み取って解析する」方がよいでしょうscanf()。エラー報告の処理が簡単です。

これらの観察結果は次のようになります。

#include <stdio.h>

int get_tuition_and_supplies(double *ptuition, double *psupplies);
int get_double(double *pvalue);

int main(void)
{
    double tuition, supplies;
    if (get_tuition_and_supplies(&tuition, &supplies) == 0)
        printf("Tuition: %.2f; supplies %.2f\n", tuition, supplies);
    return(0);
}

int get_tuition_and_supplies(double *ptuition, double *psupplies)
{
    int rc = -1;    // Failure
    printf("Enter tuition: ");
    if (get_double(ptuition) == 0)
    {
        printf("Enter supplies: ");
        if (get_double(psupplies) == 0)
            rc = 0;
    }
    return rc;
}

int get_double(double *pvalue)
{
    char buffer[4096];
    int rc = -1;
    if (fgets(buffer, sizeof(buffer), stdin) == 0)
        fprintf(stderr, "EOF (or error) reading data\n");
    else if (sscanf(buffer, "%lf", pvalue) != 1)
        fprintf(stderr, "Did not find a number in input (%.32s)\n", buffer);
    /* Could check for no extracharacters (blanks allowed) up to newline */
    else if (*pvalue < 0.0)
        fprintf(stderr, "Value (%g) may not be negative\n", *pvalue);
    else
        rc = 0;
    return rc;
}

「成功が証明されるまでリターンコード()を失敗に設定する」というイディオムは、rc検証を処理するための効果的な手法の1つです。get_double()関数にプロンプ​​トを含めて、そのシグネチャが次のようになるようにする方がよい場合があります。

int get_double(const char *prompt, double *pvalue);

これにより、コードを次のように簡略化できますget_tuition_and_supplies()

int rc = -1;    // Failure
if (get_double("Enter tuition: ", ptuition) == 0 &&
    get_double("Enter supplies: ", psupplies) == 0)
    rc = 0;
return rc;

これは、2つだけではなく、複数の値を処理するために適切に拡張されます。

于 2012-07-15T01:29:38.010 に答える
0

私にとっては、このscanfために使用するのはあまり好きではありません。これがあなたの問題に対処するために私がすることです:

  1. 文字の配列を割り当てます。入力が書き込まれるバッファとして機能します。サイズは一般的に用途を反映する必要があります。つまり、(整数型)以下の数値しか受け取らない場合は、10006文字しか割り当てません。最後の2つはと'\n'です'\0'
  2. '\n'オーバーフローを検出するには、配列の最後の要素の前の要素を初期化します。
  3. fegts()関数を使用して入力を受け取ります。
  4. 初期化した最後の要素の前の要素が変更されたかどうかを確認して、オーバーフローを確認し'\n'ます。もしそうなら、私はオーバーフローエラーを報告します、さもなければ実行を続けます。
  5. atof()または関数を使用atoi()して、それぞれdouble値またはinteger値に変換します。

私のアプローチに何らかのバグが含まれているかどうかを知りたいのですが、私が知る限り、それは問題なく機能します。

于 2012-07-15T01:11:34.313 に答える
0

私には、 get_double() の目的はユーザー入力を処理することのように思えます。だからこれは私がすることです:

#include <stdio.h>

int get_double(double *in)
{
    scanf("%d", in);
    if (*in < 0) {
        printf("error message");
        return 1;
    }
    return 0;
}

void get_income(double ptuition, double psupplies, double *pschool)
{
    *pschool = ptuition + psupplies;
}

int main(void)
{
    double ptuition, psupplies, pschool;

    printf("Enter tuition: ");
    if (get_double(&ptuition)) {
        return 1;
    }

    printf("\nEnter supplies: ");
    if (get_double(&psupplies)) {
        return 1;
    }

    get_income(ptuition, psupplies, &pschool);
    printf("Total school cost: %f", pschool);
    return 0;
}
于 2012-07-15T00:21:49.013 に答える