Då ska vi se om jag lyckats någotsånär att koda en omvänd polsk kalkylator
som är bug-fri ?
En bra övning tycker jag, både lite objektorienterat och pekare på samma gång.
Nu ska jag ge mig på bitvisa operatorer hade jag tänkt och det kan nog vara bra
om jag ska koda til Arduino.
Ska jag räkna ut
(1 + 7)*(8 - 2) + 6/3 så knappar jag in
1 7 + 8 2 - * 6 3 / +
och ska jag räkna ut 5*(6 - 4) / (3 +
6 4 - 5 * 3 8 + /
(varför blev det en gul smiles där? ska vara en 8 med ett ) efter ----> BUG!!!!!!
Ange ett tal: 1 7 + 8 2 - * 6 3 / +
digit
space
digit
space
op
space
digit
space
digit
space
op
space
op
space
digit
space
digit
space
op
space
op
resultat = 50
Ange ett tal: 6 4 - 5 * 3 8 + /
digit
space
digit
space
op
space
digit
space
op
space
digit
space
digit
space
op
space
op
resultat = 0.909091
Kod: Markera allt
//============================================================================
// Name : PolskKalkylator.cpp
// Author : 4kTRB
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <string>
#include "StackChar.h"
#include "StackDouble.h"
#include "Operand.h"
#define NUMBER '0'
using namespace std;
StackDouble stack(50);
void polishCalculator(int, double);
int main() {
Operand lineanalyzer;
StackChar symbolstack(50);
char tecken[50];
cout << "Ange ett tal: ";
cin.getline(tecken,50);
cout << NEWLINE;
symbolstack = lineanalyzer.getOperand(tecken);
cout << NEWLINE;
symbolstack.invert();
char ch[10];
char temp;
int type;
int index = 0;
int chindex = 0;
double number = 0.0;
temp = symbolstack.pop();
while((temp == 'd') || (temp == 's') || (temp == 'p') || (temp == 'o')){
if((temp == 'd') || (temp == 'p')){
while((temp == 'd') || (temp == 'p')){
ch[chindex] = tecken[index];
index++;
chindex++;
temp = symbolstack.pop();
if(temp == 'p'){
ch[chindex] = tecken[index];
index++;
chindex++;
temp = symbolstack.pop();
}
}
number = lineanalyzer.calcDouble(ch);
type = NUMBER;
polishCalculator(type,number);
chindex = 0;
for(int i = 0;i<10;i++){
ch[i] = '\0';
}
}
if(temp == 's'){
while(temp == 's'){
index++;
temp = symbolstack.pop();
}
}
if(temp == 'o'){
ch[chindex] = tecken[index];
type = tecken[index];
polishCalculator(type,number);
index++;
chindex = 0;
for(int i = 0;i<10;i++){
ch[i] = '\0';
}
temp = symbolstack.pop();
}
}
cout << "resultat = " << stack.pop() << NEWLINE;
return 0;
}
void polishCalculator(int type, double number){
double op2;
switch (type) {
case NUMBER:
stack.push(number);
break;
case '+':
stack.push(stack.pop()+stack.pop());
break;
case '*':
stack.push(stack.pop() * stack.pop());
break;
case '-':
op2 = stack.pop();
stack.push(stack.pop() - op2);
break;
case '/':
op2 = stack.pop();
if (op2 != 0.0)
stack.push(stack.pop() / op2);
else{
cout << "Error! division med noll" << NEWLINE;
stack.clean();
}
break;
default:
cout << "Error! okänt kommando " << NEWLINE;
break;
}
}
Kod: Markera allt
/*
* Operand.cpp
*
* Created on: 6 feb. 2019
* Author: 4kTRB
*/
#include "Operand.h"
using namespace std;
Operand::Operand() {
//cout << "En instans av Op" << NEWLINE;
}
Operand::~Operand() {
//cout << "En instans av Op har tagits bort." << endl;
}
StackChar Operand::getOperand(char tecken[]){
int charindex = 0;
bool spaceflag;
bool periodflag;
bool numberflag;
bool opflag;
StackChar symbolstack(50);
numberflag=number(tecken,charindex);
periodflag=period(tecken,charindex);
spaceflag=space(tecken,charindex);
opflag=operand(tecken,charindex);
while(numberflag || periodflag || spaceflag || opflag){
if(opflag){
symbolstack.push('o');
charindex++;
numberflag=number(tecken,charindex);
periodflag=period(tecken,charindex);
spaceflag=space(tecken,charindex);
opflag=operand(tecken,charindex);
}
if(periodflag){
symbolstack.push('p');
charindex++;
numberflag=number(tecken,charindex);
periodflag=period(tecken,charindex);
spaceflag=space(tecken,charindex);
opflag=operand(tecken,charindex);
}
if(spaceflag){
symbolstack.push('s');
charindex++;
numberflag=number(tecken,charindex);
periodflag=period(tecken,charindex);
spaceflag=space(tecken,charindex);
opflag=operand(tecken,charindex);
}
if(numberflag){
symbolstack.push('d');
charindex++;
numberflag = number(tecken,charindex);
periodflag = period(tecken,charindex);
spaceflag = space(tecken,charindex);
opflag = operand(tecken,charindex);
}
}
return symbolstack;
}
bool Operand::number(char tecken[],int i){
bool flag = false;
if(isdigit(tecken[i])){
cout << "digit" << NEWLINE;
flag = true;
}
return flag;
}
bool Operand::operand(char tecken[],int i){
bool flag = false;
if((tecken[i] != ' ') && (tecken[i] != '\t') && (tecken[i] != '\0')
&& (tecken[i] != '.') && (!isdigit(tecken[i]))){
cout << "op" << NEWLINE;
// if(tecken[i] == '\0')
// cout << "NULL " << tecken[i]+'0' << NEWLINE;
flag = true;
}
return flag;
}
bool Operand::period(char tecken[],int i){
bool flag = false;
if(tecken[i] == '.'){
cout << "period" << NEWLINE;
flag = true;
}
return flag;
}
bool Operand::space(char tecken[], int i){
bool flag = false;
if((tecken[i] == ' ') || (tecken[i] == '\t')){
cout << "space" << NEWLINE;
flag = true;
}
return flag;
}
double Operand::calcDouble(char tecken[]){
int index;
int temp;
int u = 0;
int heltal[10];
int decimaltal[10];
double decimaldel;
double heltalsdel;
double result;
for(index=0;index<10;++index){
heltal[index] = 0;
decimaltal[index] = 0;
}
index = 0;
temp = 0;
while(isdigit(tecken[index])){
heltal[temp] = tecken[index] - '0';
index++;
temp++;
}
heltalsdel = 0;
while(temp>0){
heltalsdel += pow (10,u)*heltal[temp-1];
temp--;
u++;
}
index++;
while(isdigit(tecken[index])){
decimaltal[temp] = tecken[index] - '0';
index++;
temp++;
}
decimaldel = 0;
u=0;
while(temp>0){
decimaldel += pow (10, 0-u-1)*decimaltal[u];
temp--;
u++;
}
result = 0.0;
result = heltalsdel + decimaldel;
return result;
}
Kod: Markera allt
/*
* Operanderand.h
*
* Created on: 14 feb. 2019
* Author: 4kTRB
*/
#pragma once
#define NEWLINE '\n'
#include <stdio.h>
#include <string>
#include <cmath>
#include "StackChar.h"
#define NUMBER '0'
#define MAXOperand 100
class Operand {
public:
Operand();
virtual ~Operand();
StackChar getOperand(char tecken[]);
double calcDouble(char tecken[]);
private:
char a[20];
bool space(char tecken[], int i);
bool period(char tecken[], int i);
bool number(char tecken[],int i);
bool operand(char tecken[],int i);
};
Kod: Markera allt
/*
* StackDouble.cpp
*
* Created on: 6 feb. 2019
* Author: 4kTRB
*/
#include "StackDouble.h"
using namespace std;
StackDouble::StackDouble(int stacksize) {
stackSize = stacksize;
allocbuf = new double[stacksize];
for (int i=0; i<stacksize; i++) {
allocbuf[i] = 0; // Initialize all elements to zero.
}
stackTopPointer = allocbuf; // peka på element noll i allocbuf
// stackTopPointer = &allocbuf[0]; // fungerar också
bool b = allocdouble(); // allokera en stack om stacksize double
if(!b){
cout << "Allokering av stack överskred STACKSIZEMAX" << NEWLINE;
cout << "STACKSIZEMAX = " << STACKSIZEMAX << NEWLINE;
}
}
StackDouble::~StackDouble(){
delete [] allocbuf;
//cout << "En instans av StackDouble har tagits bort." << endl;
}
int StackDouble::getSize(){
return stackSize;
}
void StackDouble::clean(void){
while(stackTopPointer > allocbuf){
*stackTopPointer = 0.0;
stackTopPointer--;
}
}
void StackDouble::invert(void){
int index = 0;
char c;
char temp[index];
while(index < stackSize){
temp[index] = '\0';
c = this->pop();
if(c == '\0'){
break;
}
temp[index] = c;
++index;
}
index = 0;
while(index < stackSize){
c = temp[index];
if(c == '\0'){
break;
}
this->push(c);
++index;
}
}
/**
* Allokera ett minnesområde för att lagra double.
* Avancera pekaren stackTopPointer n steg för att peka på
* start av stacken.
* Returnera true om den allokerade stacken håller
* sig inom ramen för STACKSIZEMAX annars returnera false
*/
bool StackDouble::allocdouble(){
if ((allocbuf + STACKSIZEMAX - stackTopPointer) >= stackSize){
stackTopPointer += stackSize; // peka på stackens början
return true;
} else
return false;
}
void StackDouble::push(double d){
if(stackTopPointer > allocbuf){
*stackTopPointer = d;
stackTopPointer--;
}
else{
cout << "Stacken är full" << NEWLINE;
}
}
double StackDouble::pop(){
if(stackTopPointer < (allocbuf + stackSize)){
++stackTopPointer;
return *stackTopPointer;
}
else{
cout << "Stacken är tom så noll returneras ";
return 0.0;
}
}
Kod: Markera allt
/*
* StackChar.h
*
* Created on: 11 feb. 2019
* Author: 4kTRB
*/
#pragma once
#define STACKSIZEMAX 100
#define NEWLINE '\n'
#include <iostream>
class StackChar {
public:
StackChar(int stacksize);
~StackChar();
void push(char ch);
char pop(void);
int getSize(void);
void invert(void);
private:
bool allocdouble(void);
char* allocbuf;
char* stackTopPointer;
int stackSize;
};