【问题标题】:Trouble figuring out logic for while/if loop in C无法弄清楚 C 中的 while/if 循环的逻辑
【发布时间】:2014-02-16 01:05:08
【问题描述】:

我有一些代码,我遇到问题的功能是:

unsigned int getInputData() {

    printf("Please input a positive integer number terminated with a carriage return.\n");

    do{ 
        scanf("%c", &input);

        if(isdigit(input))  {
            temp = charToInt(input);
            rValue = mergeInt(rValue, temp);
        }
        if(rValue >= imax)  {
            rValue = 0;
            printf("ERROR: That is too large of an integer. Please try again. \n");
        }
        else if(isalpha(input)){
            rValue = 0;
            printf("This is not a integer. Please try again. \n");
        }
        else{
            printf("OK. This is a good number. \n");
        }
    } while(1);
}

我正在单独扫描每个char,并将其合并到int。这正是我想要做的,但我只希望它在用户输入时打印一次"OK. This is a good number."。例如:如果有人要输入:12345 我希望它返回:"OK. This is a good number." 一次5 个字符而不是每个字符一次。希望这是有道理的,已经有一段时间了,所以任何事情都会有所帮助。

【问题讨论】:

  • 你为什么使用全局变量inputimaxrValuetemp?或者你为什么在发布代码之前删除你的变量定义?您必须错误检查scanf();否则,您将永远不知道何时点击 EOF。看来您可以输入123@123. 等,并且数字是可以的,但如果您输入123a 则不是。你真的想用什么字符来终止号码?你说得对,scanf() 没有(必然)保护自己免于溢出。你应该推回结束数字的字符吗?
  • @JonathanLeffler 抱歉,我将添加变量定义(尽管我不认为它们都是必要的)。这只是一段“快速”的代码,所以我并不担心任何溢出或类似的事情。只是希望 print 语句的行为方式也符合我的意愿。
  • 您的验证if (rValue > imax) 应该在if (isdigit(input)) 代码块中;如果您没有尝试设置rValue,那么测试溢出是没有意义的。它还会影响您的主要问题的逻辑。当你找到一个好的数字时,你应该退出do { … } while (1);循环。
  • @JonathanLeffler 我该如何退出do-while loop,同时仍单独检查每个char
  • 你的答案相当不错;我的在某些方面会很相似,但也会有所不同。总的来说,我比我更喜欢其他解决方案,尽管我的解决方案至少在某些方面更接近您的原始代码。

标签: c if-statement logic do-while


【解决方案1】:

您的代码背后存在巨大的逻辑问题:

  • 您无限循环而不检查输入结束:

您说您想在用户输入几个数字时判断这是否是一个好数字,但是您一次只读取一个字符,并且您没有定义数字的结尾方式。 尽管您确实指定以回车结束,但您并没有这样设计您的算法,您从不检查 \n 字符。

  • 您为getInputData() 函数定义了一个返回值,但您永远不会从该函数返回。
  • 您测试input 是否是一个数字来更新值,但对于错误,只有当它是一个字母字符时才会显示错误。

基本上,为了保持您编写算法的方式,这里有另一种看法:

unsigned int getInputData() {
    char input;
    long value=0;

    do {
        scanf("%c", &input);

        if (isdigit(input))
            value = value*10+input+'0';
        else if (input == '\n')
            return 1;
        else
            return 0;

    } while(1);
}

int main() {
    printf("Please input a positive integer number terminated with a carriage return.\n");

    if (getInputData() == 1)
        printf("OK. This is a good number.\n");
    else
        printf("This is not a integer. Please try again. \n");

    return 0;
}

但我确实退出了无限循环以便能够检查结果。

注意:出于示例的目的,我没有检查溢出。 NB1:我一直使用scanf() 来接近您的代码,但如果您一次只想读取一个字符,最好使用getchar(),这样更简单、更快捷. N.B.2:您还可以通过使用scanf() 的更多功能来简化您的代码:

unsigned int getInputData() {
    unsigned input;
    long value=0;
    int n;

    do {
        n = scanf("%u", &input);
        if (n == 0)
            return 0;
        else
            return 1;
    } while(1);
}

您甚至可以尝试使用scanf("%a[0-9]"),它是一个 GNU 扩展。详情请见man scanf

【讨论】:

  • 出于好奇,在用户输入正确的 int 之前如何循环?
  • 基本上:while (getInputData() != 1) { printf("This is not an integer, please try again.\n"); } printf("Good boy. This is an integer.");...其实这很明显,为什么要问这个问题?
猜你喜欢
  • 2021-08-30
  • 1970-01-01
  • 2021-01-06
  • 1970-01-01
  • 1970-01-01
  • 2016-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多