0

我需要以格式添加用户通过命令提示符给出的分数

a/b b/c

我以为我可以这样做:

n1 = atoi(argv[1]);
d1 = atoi(argv[3]);
n2 = atoi(argv[4]);
d2 = atoi(argv[6]);

从而跳过斜杠,但这只会使程序崩溃。是否有某种方法可以跳过通过命令提示符作为参数传递的某些字符?先感谢您。

4

2 回答 2

3

如果用户写:

add_fractions 1/2 2/3

那么你的程序只有 3 个参数:

argv[0] = "add_fractions"
argv[1] = "1/2"
argv[2] = "2/3"
argv[3] = 0

argc3。

您将不得不做这样的事情(在检查您是否获得了 2 个参数之后):

char *ptr;
n1 = atoi(argv[1]);
if ((ptr = strchr(argv[1], '/') != 0)
    d1 = atoi(ptr+1);
else
    d1 = 1;
n2 = atoi(argv[2]);
if ((ptr = strchr(argv[2], '/') != 0)
    d2 = atoi(ptr+1);
else
    d2 = 1;

或者您可以将重复的语句序列打包到一个函数中(逻辑稍有不同):

void read_fraction(char const *str, int *num, int *den)
{
    char *ptr;
    *num = atoi(str);
    if ((ptr = strchr(str, '/') == 0)
        ptr = "/1";
    *den = atoi(ptr+1);
}

并在main()

read_fraction(argv[1], &n1, &d1);
read_fraction(argv[2], &n2, &d2);

您可能需要考虑验证;如果字符串的第一部分没有数字,则分子变为 0,但如果有斜线并且斜线后面没有数字,则分母变为 0,这可能不是您想要的。一种解决方法是,如果 from 的atoi(ptr+1)值为 0,则将分母设置为 1。这是一种逃避,但可以防止猖獗的崩溃。或者你可以在函数体中使用另一个完全不同的实现:

int read_fraction(char const *str, int *num, int *den)
{
    if (sscanf(str, "%d/%d", num, den) != 2)
        return -1;
    return 0;
}

然后签入main()

if (read_fraction(argv[1], &n1, &d1) == 0 &&
    read_fraction(argv[2], &n2, &d2) == 0)
    ...process valid fractions...
else
    ...make appropriate comments about how to use the program...

从几个角度来看,使用函数“更好”。在The Pragmatic Programmer中,它被称为 DRY 原则:不要重复自己。

Kernighan 和 Plauger 在他们的书The Elements of Programming Style中巧妙地总结了这一点:

  • 子例程调用允许我们总结参数列表中的不规则之处,我们可以快速看到发生了什么。
  • 子程序本身总结了代码的规律性,因此不需要使用重复的模式。
于 2013-11-12T07:14:54.327 回答
2

a/bb/c

它只是在参数列表中创建 2 个条目,一个是a/b,另一个是b/c

所以,argv[0]argv[1]argv[2]有效的,并且argc3

空格对于分隔参数很重要(除非你在里面包装一个条目""

于 2013-11-12T07:14:51.263 回答