#c
#c
Вопрос:
Я написал эту простую программу-калькулятор, в которой пользователь может сохранять вычисления в переменной, которая была введена. Я не знаю, как объяснить это лучше, поэтому я продемонстрирую на примере. Если входные данные:
a = 1 2
b = 6 - 5
c = 20 * a
d = a / b
exit
Тогда вывод должен быть:
3
1
60
3
Посмотрите, как программа сохраняет значение a = 1 2
as a = 3
. Затем пользователь может свободно использовать a
в другом вычислении. Например, 20 * a
. С a = 3
этого момента 20 * a
должно быть равно 60
.
Однако в моей программе есть проблема. Если я введу следующее:
a = 1 2
b = a 3
c = a b
d = 20 * a
Затем я получаю проблему с выводом для строк 3 и 4. Результат, который я получаю, выглядит следующим образом:
3
6
55
Как вы можете видеть, он говорит, что a b = 55
, когда это необходимо 9
. И когда я пытаюсь умножить 20 * a
, я даже не получаю результат. Я предполагаю, что для этой последней строки нет выходных данных, потому что она даже не вводит случай умножения в коде. Но понятия не имею, откуда 55
берется.
Вот мой код (я знаю, что он грязный, но это потому, что я перепробовал все, чтобы исправить это, и мне не повезло):
#include <iostream>
#include <cmath>
#include <stdlib.h>
#include <sstream>
#include <string>
using namespace std;
char op='a';
double num1, num2, num3=0;
int sub1, sub2=0;
std::string temp;
int main() {
double var[26];
bool flag = false;
char eq[5];
while (true) {
getline(cin, temp);
if (temp.compare("exit") == 0) {
break;
}
std::stringstream os(temp);
int count = 0;
for(charamp; c : temp) {
if(c != ' '){
eq[count] = c;
count ;
}
}
/* for(std::string::size_type i = 0; i < temp.size(); i){
if(temp[i] != ' '){
eq[count] = temp[i];
count ;
}
}
*/
if(eq[0] >= 97 amp;amp; eq[0] <= 122){
num1 = eq[2] - 48;
op = eq[3];
num2 = eq[4] - 48;
flag = true;
}
else{
num1 = eq[0] - 48;
op = eq[1];
num2 = eq[2] - 48;
}
switch (op) {
case ' ':
if(flag == true){
var[eq[0] - 97] = num1 num2;
}
if((int)num1 >= 48 amp;amp; (int)num1 <= 57){
num1 = var[(int)num1 48 - 97];
}
if((int)num2 >= 48 amp;amp; (int)num2 <= 57){
num2 = var[(int)num2 48 - 97];
}
cout << num1 num2 << endl;
break;
case '-':
if(flag == true){
var[eq[0] - 97] = num1 - num2;
}
if((int)num1 >= 48 amp;amp; (int)num1 <= 57){
num1 = var[(int)num1 48- 97];
}
if((int)num2 >= 48 amp;amp; (int)num2 <= 57){
num2 = var[(int)num2 48- 97];
}
cout << num1 - num2 << endl;
break;
case '*':
if(flag == true){
var[eq[0] - 97] = num1 * num2;
}
if((int)num1 >= 48 amp;amp; (int)num1 <= 57){
num1 = var[(int)num1 48- 97];
}
if((int)num2 >= 48 amp;amp; (int)num2 <= 57){
num2 = var[(int)num2 48- 97];
}
cout << num1 * num2 << endl;
break;
case '/':
if(flag == true){
var[eq[0] - 97] = num1 / num2;
}
if((int)num1 >= 48 amp;amp; (int)num1 <= 57){
num1 = var[(int)num1 48- 97];
}
if((int)num2 >= 48 amp;amp; (int)num2 <= 57){
num2 = var[(int)num2 48- 97];
}
cout << num1 / num2 << endl;
break;
case '%':
sub1 = num1;
sub2 = num2;
if(flag == true){
var[eq[0] - 97] = sub1 % sub2;
}
if((int)num1 >= 48 amp;amp; (int)num1 <= 57){
num1 = var[(int)num1 48- 97];
}
if((int)num2 >= 48 amp;amp; (int)num2 <= 57){
num2 = var[(int)num2 48- 97];
}
cout << sub1 % sub2 << endl;
break;
case '^':
if(flag == true){
var[eq[0] - 97] = pow(num1, num2);
}
if((int)num1 >= 48 amp;amp; (int)num1 <= 57){
num1 = var[(int)num1 48- 97];
}
if((int)num2 >= 48 amp;amp; (int)num2 <= 57){
num2 = var[(int)num2 48- 97];
}
cout << pow(num1, num2) << endl;
break;
}
}
return 0;
}
Я думал, что проблема была в цикле for, и именно поэтому вы видите, что один цикл for задан как комментарий. Я попытался заменить его другим циклом for, но безуспешно. Я был бы очень признателен за помощь в этом, поскольку я перепробовал множество вещей, и ничего не работает. Я бы добавил сюда то, что я пробовал, но я больше не хочу делать сообщение. Если вам нужна дополнительная информация, пожалуйста, дайте мне знать.
Комментарии:
1. небольшой совет. if(флаг == true) -> просто измените на if(флаг). Намного чище.
2. кроме того … в вашем коде огромное количество магических чисел … что очень затрудняет понимание того, что вы делаете. Что такое «48» / «97» / «57»? Вы должны использовать фактический символ. например, ‘a’ для представления 97
3. @Ilan Keshet Они должны были представлять символы через их ASCII. Могу ли я просто поменять их местами с реальными символами?
4. ДА. если вы напрямую заменяете их ascii, это лучшая практика
5. Micronag: C автоматически преобразует его для вас в значение ascii int . Хорошо… Не совсем. Он преобразует символ в значение символа в кодировке символов, используемой компилятором, которая, вероятно, является ASCII, но стандарт C не требует кодировки. Это еще одна причина не использовать здесь магические числа.
'a'
всегда'a'
, но'a'
не всегда 97.
Ответ №1:
Загрузка значений из вашего var
массива должна быть выполнена до выполнения дальнейших операций, поэтому сразу после синтаксического анализа строки загрузите их следующим образом
if(eq[0] >= 97 amp;amp; eq[0] <= 122){
num1 = eq[2] - 48;
op = eq[3];
num2 = eq[4] - 48;
flag = true;
}
else{
num1 = eq[0] - 48;
op = eq[1];
num2 = eq[2] - 48;
}
if((int)num1 >= 48 amp;amp; (int)num1 <= 57){
num1 = var[(int)num1 48 - 97];
}
if((int)num2 >= 48 amp;amp; (int)num2 <= 57){
num2 = var[(int)num2 48 - 97];
}
Внутри вашего блока switch вы можете просто напрямую выполнить операцию, например. для ‘ ‘ регистр :
case ' ':
if(flag == true){
var[eq[0] - 97] = num1 num2;
}
cout << num1 num2 << endl;
break;
Комментарии:
1. Большое вам спасибо. Я действительно ценю это. Но почему код прерывается, когда я пытаюсь умножить? Например, если я сделаю a = 1 2, а затем c = 20 * a, это не сработает. Как вы упоминали ранее, некоторые операции деления также не работают.
2. Ваш код прямо сейчас обрабатывает только однозначный ввод. Опять же, используйте отладчик в вашей IDE, чтобы увидеть, что происходит
3. Я думаю, я знаю, что происходит. Когда я загружаю подобные переменные
num1 = eq[2] - 48;
, я присваиваю только то, что находится внутриeq[2]
num1
. Однакоeq[2]
правильна ли однозначная цифра? Поэтому, если я ввожу двузначное число, например 20,eq[2]
оно содержит не обе цифры, а только одну.4. Потому что я попытался сделать
b = 3 * 5
, что означалоb = 15
бы, а затем я сделалc = b 10
, и ответ вышел в 16, а не в 26. Поэтому я думаю, что он считывает только первую цифру 10, которая будет равна 1. Он не считывает обе цифры 1 и 0, чтобы получить 10. И опять же, я думаю, это потомуnum2
, что загружается какnum2 = eq[4] - 48;
whereeq[4
] именно там, где находится 1 из 10.5. Довольно много. Вы можете перебирать строку вручную и постепенно * = 10 старого значения и добавлять новое (или просто добавлять новое, деленное на коэффициент progressive / = 10, как только вы встретите десятичную точку), но вам лучше просто использовать надлежащую функциональность синтаксического анализа, встроенную в STL