【问题标题】:Simple unit converter in CC中的简单单位转换器
【发布时间】:2010-08-27 19:32:27
【问题描述】:

我为我的过程编程课程购买了“A Book on C”,并且正在完成一些练习。第 2 章练习 9 是关于设计一个可以处理盎司、磅、克和千克的单位转换器。

我编写的代码有效,但我真的认为它可以做得更简洁。使用嵌套的 if 语句似乎是一种混乱的方式。

另外,我注意到的一个问题是,如果在第 27 行给 scanf() 一个字符或字符串,它将持续存在,然后在第 95 行传递给 scanf()。例如,如果您输入“y ” 作为要转换的值,程序将转到开始,不允许用户回答“您要执行额外的转换吗?”我该如何解决这个问题,以便在输入 NaN 时将其丢弃?

我的代码可以位于: http://pastebin.com/4tST0i7T

【问题讨论】:

  • 我建议设置枚举——从 0 开始的整数表示类型。然后将转换粘贴到对称的 n x n 矩阵中。最后,用它来找到正确的系数。
  • 把代码放在这里,而不是使用pastebin。
  • SO 问题预计会出现,因此其他人可以从阅读它们和他们的答案中受益。将重要信息放在其他网站上会适得其反。请至少将代码的重要部分放在您的问题中。

标签: c


【解决方案1】:

清理 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) 从临时单位转换为输出单位。

正如其他人提到的,gets() 绝对是要走的路。

【讨论】:

  • 我正要提出类似的建议。拥有 N 个转换因子比拥有 N² 个转换因子要好得多。
  • 我真的不记得阅读完整字符串的细微差别了。不过,我知道此时您会想要阅读整行内容,而不仅仅是单个项目。
  • 执行两次转换会影响精度。
  • 没错,但精度不是问题。目标是简单的代码。
【解决方案2】:

我会这样做:

#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");
    }
}
  • 将数据存储在某种数据结构中,而不是存储在代码中。
  • 先读取一行文字,再判断是否为数字。
  • 从标准输入读取时,请考虑缓冲区的大小。
  • 使用循环而不是 goto。
  • 使用一些常用单位(例如克)来计算任何东西。

【讨论】:

    【解决方案3】:

    最可靠的方法是使用fgets()函数读取输入字符串,使用isdigit()检查是否包含数字(字符串中的所有字符),然后转换使用 atoi() 将其转换为数值。

    顺便说一句,最后两个操作可以替换为strtol()

    【讨论】:

    • NO! gets() 不安全,它允许缓冲区溢出。请改用fgets(str,len,stdin)
    猜你喜欢
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多