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 
}

我需要验证用户提供的值,tuitionsupplies确保它们都是 0 或更大且不为空。不应接受负值或数字以外的任何内容。

验证代码应该在get_double函数中,我似乎无法弄清楚如何验证驻留在单独函数中的内容。请寻求指导。

4

3 回答 3

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 回答
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是处理验证的一种有效技术。在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;

这巧妙地扩展到处理多个值,而不仅仅是两个。

于 2012-07-15T01:29:38.010 回答
0

对我来说,我真的不喜欢scanf因为这个而使用. 以下是我将如何解决您的问题:

  1. 分配字符数组。充当将写入输入的缓冲区。尺寸一般需要体现用途。也就是说,如果我只收到一个不大于1000(整数类型)的数字,那么我只会分配 6 个字符。最后两个用于'\n'and '\0'
  2. 初始化数组中最后一个元素之前的元素'\n'以检测溢出。
  3. 使用fegts()函数接收输入。
  4. 通过检查我初始化的最后一个元素之前的元素'\n'是否发生变化来检查溢出。如果是,我报告溢出错误,否则继续执行。
  5. 使用atof()oratoi()函数分别转换为双精度或整数值。

我想知道我的方法是否包含任何类型的错误,但据我所知,它工作正常。

于 2012-07-15T01:11:34.313 回答