为什么我的程序会直接跳过变量初始化之后的第一条指令?

时间:2018-11-16 22:28:34

标签: c

因此,我正在尝试编写一个从左到右计算表达式的程序(就像操作按输入顺序执行一样)。例如:

Enter an expression: 1+2.5*3
Value of expression: 10.5

因此,我应该在不使用数组或字符串的情况下执行此操作。我的想法是继续扫描字符,直到扫描的字符与0到9之间的任何数字都不同为止。然后,将字符转换为浮点数,并根据最后扫描的字符是什么,求和,乘法和未执行运算

这是我写的:

#include <stdio.h>
#include <math.h>

int main() {
  char digit = ' ';
  int counter = 0;
  int number = 0
  float reversed_number = 0, reversed_decimal = 0, reversed_number2 = 0,
        reversed_decimal2 = 0, result = 0;

  printf("Enter an expression: ");

  while(digit != '\n') {
  for(int i = 0; digit >= 48 && digit <= 57; i++){
    digit = getchar();
    number += pow(10, i)*(digit - 48);
  }
  for(int i = 0; number == 0; i++){
    reversed_number = pow(10, i)*(number / 10);
    number /= 10;
  }

  if(digit == '.'){
    for(int i = 0; digit >= 48 && digit <= 57; i++){
      digit = getchar();
      number += pow(10, i)*(digit - 48);
    }
    for(int i = 0; number == 0; i++){
      reversed_decimal = pow(10, i)*(number / 10);
      number /= 10;
      counter++;
    }
    reversed_decimal /= pow(10, counter - 1);
    reversed_number += reversed_decimal;
    counter = 0;
  }

  else if(digit == '+'){
    for(int i = 0; digit >= 48 && digit <= 57; i++){
      digit = getchar();
      number += pow(10, i)*(digit - 48);
    }
    for(int i = 0; number == 0; i++){
      reversed_number2 = pow(10, i)*(number / 10);
      number /= 10;
    }
    if(digit == '.'){
      for(int i = 0; digit >= 48 && digit <= 57; i++){
        digit = getchar();
        number += pow(10, i)*(digit - 48);
      }
      for(int i = 0; number == 0; i++){
        reversed_decimal2 = pow(10, i)*(number / 10);
        number /= 10;
        counter++;
      }
      reversed_decimal2 /= pow(10, counter - 1);
      reversed_number2 += reversed_decimal2;
      counter = 0;
    }
    result += reversed_number + reversed_number2;
  }

  else if(digit == '-'){
    for(int i = 0; digit >= 48 && digit <= 57; i++){
      digit = getchar();
      number += pow(10, i)*(digit - 48);
    }
    for(int i = 0; number == 0; i++){
      reversed_number2 = pow(10, i)*(number / 10);
      number /= 10;
    }
    if(digit == '.'){
      for(int i = 0; digit >= 48 && digit <= 57; i++){
        digit = getchar();
        number += pow(10, i)*(digit - 48);
      }
      for(int i = 0; number == 0; i++){
        reversed_decimal2 = pow(10, i)*(number / 10);
        number /= 10;
        counter++;
      }
      reversed_decimal2 /= pow(10, counter - 1);
      reversed_number2 += reversed_decimal2;
      counter = 0;
    }
    result += reversed_number - reversed_number2;
  }

  else if(digit == '*'){
    for(int i = 0; digit >= 48 && digit <= 57; i++){
      digit = getchar();
      number += pow(10, i)*(digit - 48);
    }
    for(int i = 0; number == 0; i++){
      reversed_number2 = pow(10, i)*(number / 10);
      number /= 10;
    }
    if(digit == '.'){
      for(int i = 0; digit >= 48 && digit <= 57; i++){
        digit = getchar();
        number += pow(10, i)*(digit - 48);
      }
      for(int i = 0; number == 0; i++){
        reversed_decimal2 = pow(10, i)*(number / 10);
        number /= 10;
        counter++;
      }
      reversed_decimal2 /= pow(10, counter - 1);
      reversed_number2 += reversed_decimal2;
      counter = 0;
    }
    result += reversed_number * reversed_number2;
  }

  else if(digit == '/'){
    for(int i = 0; digit >= 48 && digit <= 57; i++){
      digit = getchar();
      number += pow(10, i)*(digit - 48);
    }
    for(int i = 0; number == 0; i++){
      reversed_number2 = pow(10, i)*(number / 10);
      number /= 10;
    }
    if(digit == '.'){
      for(int i = 0; digit >= 48 && digit <= 57; i++){
        digit = getchar();
        number += pow(10, i)*(digit - 48);
      }
      for(int i = 0; number == 0; i++){
        reversed_decimal2 = pow(10, i)*(number / 10);
        number /= 10;
        counter++;
      }
      reversed_decimal2 /= pow(10, counter - 1);
      reversed_number2 += reversed_decimal2;
      counter = 0;
    }
    result += reversed_number / reversed_number2;
  }
  }

  printf("Value of expression: %g", result);

  return 0;
}

代码被编译的很好,没有任何警告,但是当我运行该程序时,发生了一些奇怪的事情,甚至没有打印出“输入表达式:”,并且它一直在监听用户的输入。我真的不明白为什么...即使代码与我的推理完全错误,它也至少应打印出第一个printf函数,因为在此之前什么都没有使程序循环。

这到底是怎么回事?因为我不知道

1 个答案:

答案 0 :(得分:2)

  

有些奇怪的事情发生了,甚至没有输出“输入表达式:”

这是由于I / O缓冲。 printf不会立即写入,而是使用缓冲区。对于stdout,这是一个行缓冲区,这意味着它只会在看到换行符时才刷新缓冲区(即写入)。由于您从不打印换行符,因此stdout不会被刷新。您可以显式刷新stdout

printf("Enter an expression: ");
fflush(stdout);
  

并且它一直在监听用户输入

一些调试打印可以揭示问题所在。

while(digit != '\n') {
    printf("Top of while digit: '%c'\n", digit);

    for(int i = 0; digit >= 48 && digit <= 57; i++){
        puts("in loop");
        digit = getchar();
        printf("  digit: '%c'\n", digit);
        number += pow(10, i)*(digit - 48);
    }
    printf("After first loop: '%c'\n", digit);
    for(int i = 0; number == 0; i++){
        printf("In second loop, number: %d\n", number);
        reversed_number = pow(10, i)*(number / 10);
        number /= 10;
    }
    printf("Digit: '%c'\n", digit);
$ ./test
Enter an expression: Top of while digit: ' '
After first loop: ' '
In second loop, number: 0
In second loop, number: 0
In second loop, number: 0
In second loop, number: 0
In second loop, number: 0
...

第一个循环看到digit,并立即退出而没有调用getchar。这样就离开了number == 0,因此第二个循环不断地运行number /= 10,它为0。

相反,如果要逐行处理,请先读取一行,然后对其进行解析。

char line[BUFSIZ];
fgets(line, sizeof(line), stdin);
for( int i = 0; line[i] != '\n' && line[i] != '\0'; i++ ) {
    printf("%c", line[i]);
}

然后,要进一步清理代码,可以使用isdigit and friends而不是检查单个ASCII代码。

    if( isdigit(*c) ) {
        printf("%c is a digit!\n", *c);
    }

或者,这是使用scanf从输入中读取和解析整数的适当时间。