2016-01-12 5 views
0

Напишите программу, которая действует как простой калькулятор «печати». Программа должна позволять пользователю вводить выражения оператора формы: number. Следующие программы должны быть распознаны программой: +, -, *, /, S. EУпражнение № 5 Глава 6 программирования в C

  • Оператор S сообщает программе, чтобы установить «аккумулятор» на набранный номер.
  • Оператор E сообщает программе, что выполнение завершено. Арифметические операции выполняются над содержимым аккумулятора с номером, введенным в качестве второго операнда.

Ниже приводится «пример запуска» показывает, как программа должна работать:

Begin Calculations 
    10 S   Set Accumulator to 10 
    = 10.000000  Contents of Accumulator 
    2/   Divide by 2 
    = 5.000000  Contents of Accumulator 
    55 -   Subtract 55 
    -50.000000 
    100.25 S  Set Accumulator to 100.25 
    = 100.250000 
    4 *    Multiply by 4 
    = 401.000000 
    0 E    End of program 
    = 401.000000 
End of Calculations. 

Вот мой код

#include <stdio.h> 

int main(void) 
{ 
char op; 
float acc = 0, num; 

printf("Begin Calculations\n"); 
while (op != 'E') { 
    scanf("%f %c", &num, &op); 
    switch (op) { 
     case '+': 
      acc += num; 
      printf("= %f\n", acc); 
      break; 
     case '-': 
      acc -= num; 
      printf("= %f\n", acc); 
      break; 
     case '*': 
      acc *= num; 
      printf("= %f\n", acc); 
      break; 
     case '/': 
      if (num == 0) { 
       printf("Division by zero\n"); 
      } 
      else { 
       acc /= num; 
       printf("= %f\n", acc); 
      } 
      break; 
     case 'S': 
      acc = num; 
      printf("= %f\n", acc); 
      break; 
     case 'E': 
      printf("= %f\n", acc); 
      break; 
     default: 
      printf("Unknown operator\n"); 
      break; 
    } 
} 
printf("End of Calculations"); 
} 

Мой код отлично работать с входом вопроса. Однако, когда я введите следующее (и выход) (так же, как входной вопрос, но без пробела между «номером» и «оператор»):

Begin Calculations 
    10S    
    = 10.000000  
    2/    
    = 5.000000  
    55-    
    -50.000000 
    100.25S   
    = 100.250000 
    4*    
    = 401.000000 
    0E 

Программой застряла, когда я ввод 0E. Я попытался изменить scanf("%f %c", &num, &op); на scanf("%f%c", &num, &op);, но он, похоже, не решил мою проблему. Не могли бы вы указать на проблему в моем коде? Пожалуйста, дайте мне подробное объяснение, потому что я относительно новый для C. Спасибо за любую помощь, которую вы можете предоставить.

+0

У вас есть * неопределенное поведение *. Значение неинициализированных нестатических локальных переменных, таких как ваша переменная 'op', * неопределенно *. Вы должны инициализировать его, прежде чем использовать его в состоянии цикла. Либо это, либо измените цикл 'do-while'. –

+5

Проблема в том, что '0E' не является допустимым числом, но' 0E12' будет. Реализация, вероятно, отвергает его и оставляет входные данные. _Always_ проверить возвращаемое значение из 'scanf()'. Если это не то, что вы ожидаете, вам нужно перейти в режим «восстановления ошибок», что может означать «отказ от корабля» (выход из программы) или «чтение строки, которая не удалась; сказать, что это не удалось; сделайте у пользователя еще один ход ». В качестве альтернативы, код может принять '0E' как число и сидит там, ожидая непустого символа для'% c'; попробуйте снова ввести 'E'. –

+0

Возможно, мне что-то не хватает, но я думаю, что UB вызвано 'while (op! = 'E')'. Реазоин один и тот же - переменная 'op' неинициализирована. К моменту включения оператора switch 'op' должен содержать что-то, если, конечно, scanf выполняется правильно. –

ответ

2

Вы читаете значение поплавка. Поэтому, если scanf видит 0E, он ожидает больше цифр, поскольку он считает, что вы вводите экспоненту, например. 0E5 (= 0 * 10^5). Вот почему ваша программа застряла на этом этапе. Я бы предложил использовать другого персонажа, чтобы избежать этой двусмысленности.

Если, с другой стороны, scanf видит 0S, он будет выводить 0.0 в качестве значения поплавка и «S» в качестве символа, так как «S» никогда не является действительной частью значения поплавка.

+0

Спасибо вам большое. Меняя характер, отличный от «e», а «E» исправил мою проблему. Я забыл о e в номере с плавающей запятой. –

+0

Не могли бы вы отметить его как правильный ответ? Спасибо! – Georg

Смежные вопросы