在 C 中为多个变量定义条件时出现问题

Problem while defining conditions for multiple variables in C

我正在尝试用 C 编写一个程序,它接收三个整数并使用 This Method

但我只希望输入在1-100范围内(包括1和100)

#include <stdio.h>

int main(){
    int a , b , c = 50;
    do{
        scanf("%d %d %d", &a, &b, &c);
    }
    while((a > 100 || a < 1)&& (b > 100 || b < 1) && (c > 100 || c < 1));
    
    if (a+b > c && a+c>b && b+c>a){
        printf("%d\n", a+b+c);
    }
    else {
        printf("invalid\n");
    }

而且它不知何故不考虑条件 例如,如果我输入类似 1000 -5 4 的内容,它不会再次提示我输入新的内容

但奇怪的是,如果我只考虑其中一个条件,它可以很好地处理那个变量!例如,如果我把 while((a > 100 || a < 1); 之类的东西放在那里,它就会拒绝 1000 2 4 这样的输入 我如何让它考虑所有变量的条件? 如有任何帮助,我们将不胜感激!

要检查范围内的任何变量,更改

 while((a > 100 || a < 1)&& (b > 100 || b < 1) && (c > 100 || c < 1));
                         ^^
 // Will produce a FALSE value if 'a' is within expected range, and due to
 // short-circuit, it'll not evaluate other conditions.

 while((a > 100 || a < 1) || (b > 100 || b < 1) || (c > 100 || c < 1));
                          

也就是说,还有其他几点:

  • int a , b , c = 50; 仅初始化 c,其他变量未初始化且包含不确定值。更明确一点,在单独的行中声明和定义每个变量(不是技术要求,为了可读性和可维护性,同时在技术上是正确的)。
  • 在使用扫描值之前,请始终检查 scanf() 是否成功。更好的是,取消用户输入的 scanf() 并改用 fgets()

更具可读性:

while(!( 1 <= a && a <= 100 && 1 <= b && b <= 100 && 1 <= c && c <= 100));

仅当 abc 的所有三个 超出范围时,您的循环才会继续 - 在您的示例中1000 -5 4 的条件 (c > 100 || c < 1) 的计算结果为假 (0),因此 整个表达式 的计算结果为假,循环退出。

您需要更改测试的含义,以便在 any of ab 或 [=15= 时它会继续] 超出范围。有几种方法可以做到这一点:

while ( (a < 1 || a > 100) || (b < 1 || b > 100) || (c < 1 || c > 100) );

&& 更改为 || 意味着如果 of a 中的任何一个 则表达式的计算结果为真并且循环将继续、bc 超出范围。

另一种选择:

while ( !(1 <= a && a <= 100) && (1 <= b && b <= 100) && (1 <= c && c <= 100 ) );

如果abc的三个都是,这将导致循环退出在范围内。

您还应该检查 scanf 的结果以确保您阅读了所有 3 个输入:

do 
{
  if ( scanf ( "%d %d %d", &a, &b, &c ) != 3 ) )
  {
    if ( feof( stdin ) || ferror( stdin ) )
    {
      fputs( "Error or EOF on input, exiting", stderr );
      return EXIT_FAILURE;
    }
    else
    {
      fputs( "Bad input detected, clearing input stream", stderr );
      /**
       * Read and discard everything up to the next newline character
       */
      while ( getchar() != '\n' )
        ; // empty loop
      
      /**
       * Unconditionally branch back to the beginning of the loop since 
       * at least one of a, b, and c wasn't read at all (i.e., don't
       * rely on the test since what you're testing isn't valid).  
       */
      continue;
    }
  }
} while ( (a < 1 || a > 100) || (b < 1 || b > 100) || (c < 1 || c > 100 ) );