【问题标题】:Do-while loop not observing truth assignment (C) [closed]Do-while 循环未观察到真值分配(C)[关闭]
【发布时间】:2015-09-08 20:45:13
【问题描述】:

我的 C 项目是一个 Windows 控制台应用程序,它从用户的音乐项目中获取拍号和 BPM,并以秒为单位返回小节的长度。
我正在尝试使用 do-while 循环来添加“继续/退出?”在每次成功计算结束时提示 这是该函数的源代码。它根据用户输入执行一次计算,然后终止。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char timeSignature[6];
    float BPM;
    float beatsPerBar;
    float barLength;

    printf("Enter the working time signature of your project:");
    scanf("%s",timeSignature);

    beatsPerBar = timeSignature[0]-'0';

    printf("Enter the beats per minute:");
    scanf("%f", &BPM);

    barLength = BPM / beatsPerBar;

    printf("%f\n", barLength);
    return 0;
}

每次计算成功后,我想提示用户选择“y”返回初始输入提示或“n”结束程序并退出命令提示。 稍后的更新包括一个 do-while 循环,旨在添加该功能。

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <unistd.h>

int main()
{

    do{

        char timeSignature[6];
        char anotherCalculation;
        float BPM;
        float beatsPerBar;
        float barLength;

        printf("Enter the working time signature of your project:");
        scanf("%s",timeSignature);

        beatsPerBar = timeSignature[0]-'0';
        /*
         * Subtracts the integer value of the '0' character (48) from the integer value
         * of the character represented by the char variable timeSignature[0] to return
         * an integer value equal to the number character itself.
         */

        printf("Enter the beats per minute:");
        scanf("%f", &BPM);

        barLength = BPM / beatsPerBar;

        printf("%f\n", barLength);

        Sleep(3);

        printf("Would you like to do another calculation? (Y/N)");
        scanf(" %c", &anotherCalculation);

    }while((anotherCalculation = 'Y'||'y'));

    if((anotherCalculation != 'Y'||'y'))
        {
        printf("Goodbye!");
        return 0;
        }

    return 0;
}

当我编译时,没有错误,但当我运行它时,程序在任何输入后循环。为什么代码忽略了我的真实分配?我该怎么做才能解决这个问题?

【问题讨论】:

  • emmmm。循环在哪里?
  • 您发布的代码中没有 do-while 循环。
  • 抱歉,我花了一点时间来查看/修复它。
  • 这一行:if((anotherCalculation != 'Y'||'y')) 完全没有必要,也不会产生预期的结果。这是不必要的,因为“while()”语句已经检查过了。它不会按预期工作,因为在 C 中一次只能检查一个条件,建议:if((anotherCalculation != 'Y' &amp;&amp; anotherCalculation != 'y')) 然而,正如我所说,完全不需要这个“if”语句
  • 以秒为单位的柱形时间计算 barLength = BPM / beatsPerBar 不正确(反转)。应该是barLength = beatsPerBar * 60.0 / BPM

标签: c loops do-while truthiness


【解决方案1】:

改变这个:

while (anotherCalculation = 'Y'||'y')

到这里:

while(anotherCalculation == 'Y'|| anotherCalculation == 'y')

否则你会这样做:

while (anotherCalculation = ('Y'||'y'))

注意,我还将分配 = 更改为比较 ==

稍后您的if 也一样:

if (anotherCalculation != 'Y'||'y')

应该是:

if (anotherCalculation != 'Y'|| anotherCalculation != 'y')

顺便说一句,if 是多余的,你已经离开了while 循环,所以用户不需要更多的计算。

【讨论】:

    【解决方案2】:

    在进行比较之前将您的值转换为大写字母:

    while(toupper(anotherCalculation) == 'Y');
    

    这将接受小写或大写的'Y',并保持您的代码简单明了。

    【讨论】:

    • 'toupper()' 可以正常工作,但是;出于什么原因,OP 想要与这两个角色进行比较
    【解决方案3】:

    您的问题在于以下代码行:

    while((anotherCalculation = 'Y'||'y'));
    

    您的第一个问题是您要分配给变量anotherCalculation,然后测试该值。这是因为在 C 中,=(赋值)运算符可以在测试语句中使用,并且设置的值将返回到语句中,基本上使您的测试语句如下:

    while('Y'||'y');
    

    即使将= 替换为==,您的测试语句中的逻辑也存在错误,
    你实际上在做什么是一样的:

    TRUE 如果anotherCalculation == 'Y''y'
    由于'y' 实际上有一个值,而FALSE 在标准C 中是0,因此您的循环将持续运行,因为它总是有一个TRUE 值。

    要修复所有错误,该行实际需要的是:

    while(anotherCalculation == 'Y'|| anotherCalculation == 'y');
    

    最后,如果您想让这段代码更具可读性并避免重复测试,您可以将输入转换为大写并进行测试:

    while(toupper(anotherCalculation) == 'Y');
    

    【讨论】:

      【解决方案4】:

      首先,您使用数学符号进行逻辑检查,这在 C 中没有意义,并且您使用的是赋值 = 运算符而不是“等价测试”== 运算符。

      }while((anotherCalculation = 'Y'||'y'));
      

      应该是:

      }while((anotherCalculation == 'Y'|| anotherCalculation == 'y'));
      

      Second, save yourself some hassle down the road, and use fgets() to get a line of a text, and parse it

      最后,使用scanf()fgets() 阅读诸如“尾随换行符”之类的内容。 The scanf() function, for example, won't "eat up" the newline at the end of your input, and you'll get unexpected behavior. This very question appears on SO once per month at least.

      【讨论】:

        【解决方案5】:

        逻辑运算符不是这样工作的。 x == a || b 不会评估为“x 等于 ab 之一”;相反,它评估为“x 等于布尔表达式的结果 (a OR b)”。如果要将x 与不同的值进行比较,则必须将其写为

        x == a || x == b 
        

        但是您还有另一个问题,您使用了赋值运算符=,而您的本意是使用比较运算符==1

        while((anotherCalculation = 'Y'||'y'))
                                  ^
                                  |
                                ooops
        

        您正在执行两个非零值的逻辑或运算,结果为 1(真),并且将结果分配anotherCalculation。表达式的结果是赋值(1)后anotherCalculation的值,所以你已经有效地写了

        while( true )
        

        您需要使用== 运算符进行相等比较,并且您必须在|| 运算符的每一侧进行显式比较:

        while ( anotherCalculation == 'Y' || anotherCalculation == 'y' )
        

        在进行比较之前,您可以通过将输入转换为特定情况来稍微清理一下,从而完全不需要 || 运算符:

        while ( tolower( anotherCalculation ) == 'y' )
        

        while ( toupper( anotherCalculation) == 'Y' )
        


        1。 一位名叫 Lee 的聪明年轻程序员
        希望在 i 为 3 时循环
        当写=
        他忘记了它的续集
        从而无限循环

        【讨论】:

          【解决方案6】:

          这不是你所期望的:

          }while((anotherCalculation = 'Y'||'y'));
          

          这也不是:

          if((anotherCalculation != 'Y'||'y'))
          

          你应该这样做:

          }while((anotherCalculation == 'Y') || (anotherCalculation =='y'));
          

          还有这个:

          if((anotherCalculation != 'Y') && (anotherCalculation !='y'))
          

          【讨论】:

            【解决方案7】:

            TLDR;将您的条件更改为

            while( anotherCalculation == 'Y' || anotherCalculation == 'y' );
            

            【讨论】:

              猜你喜欢
              • 2018-05-09
              • 2015-04-24
              • 2018-01-16
              • 2016-09-23
              • 2022-01-22
              • 1970-01-01
              • 2018-08-22
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多