我为我的程序编程课购买了“A Book on C”,我正在进行一些练习。第2章练习9是关于设计一个可以使用盎司,磅,克和千克的单位转换器。
我写的代码有效,但我认为它可以做得更清洁。使用嵌套的if语句似乎是一种混乱的方式。
另外,我注意到的一个问题是如果在第27行给scanf()一个字符或字符串,它将保持不变,然后传递给第95行的scanf()。例如,如果你输入“y “作为要转换的值,程序将在不允许用户回答的情况下转到”您是否要执行其他转换?“我怎样才能解决这个问题,以便在输入NaN时将其丢弃?
我的代码位于: http://pastebin.com/4tST0i7T
答案 0 :(得分:2)
清理if结构的一种方法是将值从“fromUnit”转换为公共值,然后将其转换为“toUnit”。它只留下两个if结构,从而简化了结构。 (它也可以更好地扩展。)所以,它会更像是:
if (!strcmp(fromUnit, "pound")) {
tempval = input / 16;
} else if (!strcmp(fromUnit, "gram") == 0) {
tempval = input * OUNCESTOGRAMS;
}
if (!strcmp(toUnit, "pound")) {
output = tempval * 16;
} else if (!strcmp(toUnit, "gram")) {
output = tempval / OUNCESTOGRAMS;
}
当然,这个数学不正确,它就是这个例子。你只需要(1)选择你想要使用的临时单元(2)从输入单元转换到该单元,(3)从临时单元转换到输出单元。
正如其他人提到的那样,获取()肯定是要走的路。
答案 1 :(得分:1)
我会这样做:
#include <stdio.h>
typedef struct _unit {
char * name;
float grams;
} unit;
unit units[] = {
{"gram", 1.0},
{"kilogram", 1000.0},
{"pound", 500.0},
{"ounce", 28.3495231}
};
unit * search_unit(char * name)
{
int i;
for (i = 0; i < (sizeof(units) / sizeof(unit)); i++)
{
printf("%d %s\n", i, units[i].name);
if (0 == strcmp(units[i].name, name))
{
return & units[i];
}
}
return NULL;
}
int main() {
char line[10];
char unitname[10];
int number;
unit * found_unit;
while (1)
{
fgets(line, sizeof(line), stdin);
if (1 == sscanf(line, "%d", &number))
{
break;
}
printf("not a number\n");
}
while (1)
{
fgets(line, sizeof(line), stdin);
sscanf(line, "%s\n", unitname);
found_unit = search_unit(unitname);
if (found_unit)
{
printf("%d %s is %f grams\n", number, unitname, found_unit->grams * number);
break;
}
printf("unknown unit\n");
}
}
答案 2 :(得分:0)
最可靠的方法是使用 fgets()函数读取输入字符串,使用 isdigit()(字符串中的所有字符)检查它是否包含数字然后转换使用 atoi()将其转换为数值。
顺便说一下,最后两个操作可以用 strtol()代替。