代码有很多问题,包括:
- 不检查
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;
这巧妙地扩展到处理多个值,而不仅仅是两个。