From the calculate result function I have within my Singleton processor class, whenever I plug in 2+2 into the calculator, it returns 6. It seems like its hitting my loop an extra time and I'm not sure if its because of my delimiter while tokenizing, or if it is an error with my logic. I've seen some examples of tokenizing where they break it into two different functions and store it within a vector, but I am not sure if that would be more complicated than fixing what I already have. I'm indifferent to the way we fix it, I just want to make sure that I get the calculator to return the correct results again. I will provide my files in a code block below, thank you for taking the time to read over my message and potentially help me. If there is anything I can do to provide more information on what I have tried or how we should go about it please let me know :)
Below is App.h ------------------------------- #pragma once #include "wx/wx.h" class Window; class App : public wxApp { Window* window = nullptr; public: virtual bool OnInit(); }; End of App.h ---------------------------------- App.Cpp #include "App.h" #include "window.h" //We want App to run first this is where we implement it wxIMPLEMENT_APP(App); //Lecture Example Setup Opening Window bool App::OnInit() { window = new Window("Calculator", wxDefaultPosition, wxSize(400,600)); window->Show(); return true; } End of App.cpp -------------------------------------- ButtonFactory.h #pragma once #include "wx/wx.h" class ButtonFactory { public: //initialize buttons with pointers //change main to take a label static wxButton* CreateButton(wxWindow* parent, wxWindowID id, const wxString& label); static wxButton* CreateNumButton(wxWindow* parent, wxWindowID id, const wxString& label); static wxButton* CreateAddButton(wxWindow* parent, wxWindowID id); static wxButton* CreateSubButton(wxWindow* parent, wxWindowID id); static wxButton* CreateMultButton(wxWindow* parent, wxWindowID id); static wxButton* CreateDivButton(wxWindow* parent, wxWindowID id); static wxButton* CreateModButton(wxWindow* parent, wxWindowID id); static wxButton* CreateDecButton(wxWindow* parent, wxWindowID id); static wxButton* CreateNegButton(wxWindow* parent, wxWindowID id); static wxButton* CreateClrButton(wxWindow* parent, wxWindowID id); static wxButton* CreateSinButton(wxWindow* parent, wxWindowID id); static wxButton* CreateCosButton(wxWindow* parent, wxWindowID id); static wxButton* CreateTanButton(wxWindow* parent, wxWindowID id); static wxButton* CreateBackButton(wxWindow* parent, wxWindowID id); static wxButton* CreateEqualButton(wxWindow* parent, wxWindowID id); private: static wxButton* CreateOperatorButton(wxWindow* parent, wxWindowID id, const wxString& label); }; End of ButtonFactory.h ------------------------------------------- ButtonFactory.cpp #include "ButtonFactory.h" wxButton* ButtonFactory::CreateButton(wxWindow* parent, wxWindowID id, const wxString& label) { return new wxButton(parent, id, label); } wxButton* ButtonFactory::CreateNumButton(wxWindow* parent, wxWindowID id, const wxString& label) { return CreateButton(parent, id, label); } wxButton* ButtonFactory::CreateAddButton(wxWindow* parent, wxWindowID id) { return CreateOperatorButton(parent, id, " + "); } wxButton* ButtonFactory::CreateSubButton(wxWindow* parent, wxWindowID id) { return CreateOperatorButton(parent, id, "-"); } wxButton* ButtonFactory::CreateMultButton(wxWindow* parent, wxWindowID id) { return CreateOperatorButton(parent, id, "*"); } wxButton* ButtonFactory::CreateDivButton(wxWindow* parent, wxWindowID id) { return CreateOperatorButton(parent, id, "/"); } wxButton* ButtonFactory::CreateModButton(wxWindow* parent, wxWindowID id) { return CreateOperatorButton(parent, id, "%"); } wxButton* ButtonFactory::CreateDecButton(wxWindow* parent, wxWindowID id) { return CreateButton(parent, id, "."); } wxButton* ButtonFactory::CreateNegButton(wxWindow* parent, wxWindowID id) { return CreateButton(parent, id, "Neg"); } wxButton* ButtonFactory::CreateClrButton(wxWindow* parent, wxWindowID id) { return CreateButton(parent, id, "Clear"); } wxButton* ButtonFactory::CreateSinButton(wxWindow* parent, wxWindowID id) { return CreateOperatorButton(parent, id, "sin"); } wxButton* ButtonFactory::CreateCosButton(wxWindow* parent, wxWindowID id) { return CreateOperatorButton(parent, id, "cos"); } wxButton* ButtonFactory::CreateTanButton(wxWindow* parent, wxWindowID id) { return CreateOperatorButton(parent, id, "tan"); } wxButton* ButtonFactory::CreateBackButton(wxWindow* parent, wxWindowID id) { return CreateButton(parent, id, "<-"); } wxButton* ButtonFactory::CreateEqualButton(wxWindow* parent, wxWindowID id) { return CreateOperatorButton(parent, id, " = "); } wxButton* ButtonFactory::CreateOperatorButton(wxWindow* parent, wxWindowID id, const wxString& label) { wxButton* button = CreateButton(parent, id, label); return button; } End of ButtonFactory.cpp ------------------------------------- SingletonProcessor.h #pragma once #include class ProcessorSingleton { public: static ProcessorSingleton* GetInstance(); double Calculate(const wxString& expression); private: ProcessorSingleton() = default; static ProcessorSingleton* instance; }; End of SingletonProcessor.h ---------------------------------- Below is SingletonProcessor.cpp //this is where the problem exists #include "SingletonProcessor.h" #include #include //pointers ProcessorSingleton* ProcessorSingleton::instance = nullptr; ProcessorSingleton* ProcessorSingleton::GetInstance() { if (!instance) { instance = new ProcessorSingleton(); } return instance; } double ProcessorSingleton::Calculate(const wxString& expression) { // Implement the Shunting Yard Algorithm for expression evaluation wxStringTokenizer tokenizer(expression, " "); double result = 0; wxString lastOp; while (tokenizer.HasMoreTokens()) { wxString token = tokenizer.GetNextToken(); if (token.IsNumber()) { double number; token.ToDouble(&number); // Perform calculations based on operators // Implement Shunting Yard logic here result += number; } else { lastOp = token; } } return result; } End of SingletonProcessor.cpp ------------------------------------------ Window.h #pragma once #include "wx/event.h" #include "wx/sizer.h" #include #include #include #include class Window : public wxFrame { public: Window(const wxString& title, const wxPoint& pos, const wxSize& size); private: wxTextCtrl* textBox; void OnButtonClicked(wxCommandEvent& event); wxDECLARE_EVENT_TABLE(); //24 buttons //6 Rows x 4 Columns }; End of Window.h -------------------------------------- Window.cpp #include "Window.h" #include #include #include #include "ButtonFactory.h" #include "SingletonProcessor.h" //THIS IS WHERE THE UI DESIGN TAKES PLACE wxBEGIN_EVENT_TABLE(Window, wxFrame) EVT_BUTTON(wxID_ANY, Window::OnButtonClicked) wxEND_EVENT_TABLE() //no parent window since this is beginning of UI(so we put nullptr) //normally you need to pass through ID but using ID Any since its the parent //then passes in title //wxPoint tells us where to create the window (based off of upper left hand corner) //then window size Window::Window(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(nullptr, wxID_ANY, "Calculator Window", wxPoint(250, 200), wxSize(465, 600)) { //create sizers for UI instead of hardcoded points like last time wxBoxSizer* calcSizer = new wxBoxSizer(wxVERTICAL); //textBox //with alignment parameters textBox = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_RIGHT); calcSizer->Add(textBox, 0, wxEXPAND | wxALL, 5); //6 rows 4 cloumns wxGridSizer* buttonGrid = new wxGridSizer(6, 4, 3, 3); //Create Other Buttons buttonGrid->Add(ButtonFactory::CreateAddButton(this, wxID_ANY), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateSubButton(this, wxID_ANY), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateMultButton(this, wxID_ANY), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateDivButton(this, wxID_ANY), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateModButton(this, wxID_ANY), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateClrButton(this, wxID_ANY), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateDecButton(this, wxID_ANY), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateSinButton(this, wxID_ANY), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateCosButton(this, wxID_ANY), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateTanButton(this, wxID_ANY), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateEqualButton(this, wxID_ANY), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateBackButton(this, wxID_ANY), 0, wxEXPAND); //Button factory for buttons //Create Num Buttons buttonGrid->Add(ButtonFactory::CreateNumButton(this, wxID_ANY, "0"), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateNumButton(this, wxID_ANY, "1"), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateNumButton(this, wxID_ANY, "2"), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateNumButton(this, wxID_ANY, "3"), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateNumButton(this, wxID_ANY, "4"), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateNumButton(this, wxID_ANY, "5"), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateNumButton(this, wxID_ANY, "6"), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateNumButton(this, wxID_ANY, "7"), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateNumButton(this, wxID_ANY, "8"), 0, wxEXPAND); buttonGrid->Add(ButtonFactory::CreateNumButton(this, wxID_ANY, "9"), 0, wxEXPAND); calcSizer->Add(buttonGrid, 1, wxEXPAND | wxALL, 5); SetSizer(calcSizer); //reate my own font //xFont myFont(16, wxFONTFAMILY_ROMAN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD); //extBox->SetFont(myFont); //extBox->SetMaxLength(15); } //tester to see if buttons are working void Window::OnButtonClicked(wxCommandEvent& event) { wxButton* button = wxDynamicCast(event.GetEventObject(), wxButton); if (button) { wxString label = button->GetLabel(); wxString currentText = textBox->GetValue(); if (label == " = ") { // Use Singleton Processor algorithim to calculate the result double result = ProcessorSingleton::GetInstance()->Calculate(currentText); currentText = wxString::Format("%.2f", result); } else { // Handle other button clicks similarly if (label.IsNumber()) { currentText += label; } else if (label == " + " || label == "-" || label == "*" || label == "/" || label == "%" || label == "sin" || label == "cos" || label == "tan") { currentText += " " + label + " "; } // Add more conditions for other buttons else if (label == "Clear") { currentText = ""; } // For custom buttons created in ButtonFactory // else if (label == "CustomButtonLabel") // { // // Handle the custom button // } } textBox->SetValue(currentText); } } End of Window.cpp