I have been tasked to create a calculator on a C# web application, however I noticed that when I use variables set in other buttons, the programs sets them to 0, specifically the 'num' and 'sign' variable which I assigned in the PlusBut but when actually using them in the EqualBut they are assigned to 0. My code works in a windows form but this is my first time using website application.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1 {
public partial class About: System.Web.UI.Page {
int sign;
double num, num2;
protected void Page_Load(object sender, EventArgs e) { }
protected void Button4_Click(object sender, EventArgs e) { }
protected void But0_Click(object sender, EventArgs e) {
AnswerBox.Text = AnswerBox.Text + "0";
}
protected void But1_Click(object sender, EventArgs e) {
AnswerBox.Text = AnswerBox.Text + "1";
}
protected void But2_Click(object sender, EventArgs e) {
AnswerBox.Text = AnswerBox.Text + "2";
}
protected void But3_Click(object sender, EventArgs e) {
AnswerBox.Text = AnswerBox.Text + "3";
}
protected void But4_Click(object sender, EventArgs e) {
AnswerBox.Text = AnswerBox.Text + "4";
}
protected void But5_Click(object sender, EventArgs e) {
AnswerBox.Text = AnswerBox.Text + "5";
}
protected void But6_Click(object sender, EventArgs e) {
AnswerBox.Text = AnswerBox.Text + "6";
}
protected void But7_Click(object sender, EventArgs e) {
AnswerBox.Text = AnswerBox.Text + "7";
}
protected void But8_Click(object sender, EventArgs e) {
AnswerBox.Text = AnswerBox.Text + "8";
}
protected void But9_Click(object sender, EventArgs e) {
AnswerBox.Text = AnswerBox.Text + "9";
}
protected void PlusBut_Click(object sender, EventArgs e) {
num = double.Parse(AnswerBox.Text);
AnswerBox.Text = "";
sign = 1;
}
protected void DecBut_Click(object sender, EventArgs e) {
AnswerBox.Text = AnswerBox.Text + ".";
}
protected void MinusBut_Click(object sender, EventArgs e) {
num = double.Parse(AnswerBox.Text);
AnswerBox.Text = "";
sign = 2;
}
protected void MultBut_Click(object sender, EventArgs e) {
num = double.Parse(AnswerBox.Text);
AnswerBox.Text = "";
sign = 3;
}
protected void DivButton_Click(object sender, EventArgs e) {
num = double.Parse(AnswerBox.Text);
AnswerBox.Text = "";
sign = 4;
}
protected void EqualBut_Click(object sender, EventArgs e) {
num2 = double.Parse(AnswerBox.Text);
AnswerBox.Text = "" + num + " " + num2 + " " + sign;
}
}
}
Essentially when you trigger a postback (by clicking a button in your case), a new instance of the About class is created and the previous values of your fields are lost.
You should read about ASP Page Life Cycle Events.
There are multiple approaches to making variables persistent, one is to use Session or ViewState variables, which is probably the simplest solution in your case and should be sufficient for a calculator.
double num1
{
get { return Convert.ToDouble(ViewState["num1"] ?? 0); }
set { ViewState["num1"] = value; }
}
Another approach would be to use JavaScript to avoid postbacks, however that would increase the complexity of your app by combining client side and server side actions.
I'm guessing a bit, but I think your problem is that web applications don't persist from one button press to another. Every time the user presses a button, the browser sends a request to the server. The server creates the web application and gives it the request, and the application produces the result.
You need to persist values from one request to the next. There are several ways to do this, but it's normal to save them to a session. The exact implantation depends on what web technology you're using.
ASP.NET is server side. So each time a click is triggered at client side a new instance of About is created and sign, num and num2 are created with default value (aka 0).
Either change to a client side programming language as JavaScript or define the values as static. Static variables are linked to the class and not an instance of it, so they will hold the value between callbacks:
public partial class About : System.Web.UI.Page
{
static int sign;
static double num;
static double num2;
/* ... */
protected void PlusBut_Click(object sender, EventArgs e)
{
About.num = double.Parse(AnswerBox.Text);
AnswerBox.Text = "";
sign = 1;
}
}
Related
First of all I'm sorry for the bad title. I'm a beginner so I don't have the vocabulary to accurately express what I need help with within one sentence.
I am currently trying to program a calculator. The calculator looks like this:
All of the buttons in the left area are working perfectly, but I'm having trouble coding for the buttons on the right. The program works by simply taking the string in the display and calculating it, but that doesn't work with the buttons on the right. For example I want the display to show √x and calculate the answer by using Math.Sqrt(x) when the user presses the √-button, I don't want the display to show Math.Sqrt(x).
My code looks like this:
public partial class Calculator : Form
{
String mathOperator;
public Calculator()
{
InitializeComponent();
}
private void number_Click(object sender, EventArgs e)
{
if (tbxDisplay.Text == "0")
{
tbxDisplay.Clear();
}
Button btnNumber = (Button)sender;
tbxDisplay.Text = tbxDisplay.Text + btnNumber.Text;
}
private void btnClear_Click(object sender, EventArgs e)
{
tbxDisplay.Text = "0";
}
private void operator_Click(object sender, EventArgs e)
{
Button btnOperator = (Button)sender;
mathOperator = btnOperator.Text;
if ((btnOperator.Text == "(" ) && tbxDisplay.Text == "0")
{
tbxDisplay.Clear();
tbxDisplay.Text = tbxDisplay.Text + btnOperator.Text;
}
else
{
tbxDisplay.Text = tbxDisplay.Text + btnOperator.Text;
}
}
private void btnCalculate_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
var v = dt.Compute(tbxDisplay.Text, "");
string answer = v.ToString();
answer = answer.Replace(',', '.');
if (answer.Contains(".0"))
{
answer = answer.TrimEnd('0');
if (answer.EndsWith("."))
answer = answer.TrimEnd('.');
}
tbxDisplay.Text = answer;
}
private void btnDelete_Click(object sender, EventArgs e)
{
if (tbxDisplay.Text.Length > 0 && tbxSDisplay.Text.Length != 1)
{
tbxDisplay.Text =
tbxDisplay.Text.Remove(tbxDisplay.Text.Length - 1, 1);
}
if (tbxDisplay.Text.Length == 1)
{
tbxDisplay.Text = "0";
}
}
private void btnBack_Click(object sender, EventArgs e)
{
Form1 form1 = new Form1();
form1.Show();
this.Hide();
}
private void btnPi_Click(object sender, EventArgs e)
{
tbxDisplay.Text = tbxDisplay.Text + "3.14159265359";
//this is my solution for now
//but as you can see it's very ugly
}
}
I am making a calculator in c#. the equation by the user is displayed in a textbox called textBoxInput and the result is displayed in labelResult. When I hit the 'equals' button a System.FormatException Exception occurs at secondInt = int.Parse(textBoxInput.Text); which to me means that the program is trying to convert the operator into an int aswell as the integers input by the user in textBoxInput. My question is how can I make the program just convert the first and secondInts's without trying to convert the operator aswell? I want to keep the entire equation in textBoxInput while the result is displayed in labelResult. Here is the enitre code for the calculator class which the problem exists in.
public partial class Calculator : Form
{
int firstInt;
int secondInt;
int result;
string Operator;
Boolean Op;
public Calculator()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
textBoxInput.Text += ("1");
}
private void button2_Click(object sender, EventArgs e)
{
textBoxInput.Text += ("2");
}
private void button3_Click(object sender, EventArgs e)
{
textBoxInput.Text += ("3");
}
private void button4_Click(object sender, EventArgs e)
{
textBoxInput.Text += ("4");
}
private void button5_Click(object sender, EventArgs e)
{
textBoxInput.Text += ("5");
}
private void button6_Click(object sender, EventArgs e)
{
textBoxInput.Text += ("6");
}
private void button7_Click(object sender, EventArgs e)
{
textBoxInput.Text += ("7");
}
private void button8_Click(object sender, EventArgs e)
{
textBoxInput.Text += ("8");
}
private void button9_Click(object sender, EventArgs e)
{
textBoxInput.Text += ("9");
}
private void button10_Click(object sender, EventArgs e)
{
textBoxInput.Text += ("0");
}
private void labelResult_Click(object sender, EventArgs e)
{
}
private void buttonEquals_Click(object sender, EventArgs e)
{
Calculations application = new Calculations();
secondInt = int.Parse(textBoxInput.Text);
switch (Operator)
{
case "/":
result = application.Division(firstInt, secondInt);
labelResult.Text = (firstInt + " / " + secondInt + "\n" + "= " + result);
break;
case "+":
result = application.Addition(firstInt, secondInt);
labelResult.Text = (firstInt + " + " + secondInt + "\n" + "= " + result);
break;
case "-":
result = application.Subtract(firstInt, secondInt);
labelResult.Text = (firstInt + " - " + secondInt + "\n" + "= " + result);
break;
case "*":
result = application.Multiply(firstInt, secondInt);
labelResult.Text = (firstInt + " * " + secondInt + "\n" + "= " + result);
break;
}
}
private void buttonAdd_Click(object sender, EventArgs e)
{
firstInt = int.Parse(textBoxInput.Text);
textBoxInput.Text += (" + ");
Op = true;
Operator = "+";
}
private void buttonClear_Click(object sender, EventArgs e)
{
textBoxInput.Text = "";
labelResult.Text = "";
}
private void buttonMultiply_Click(object sender, EventArgs e)
{
firstInt = Convert.ToInt32(textBoxInput.Text);
Operator = "*";
textBoxInput.Text += (" * ");
}
private void buttonSubtract_Click(object sender, EventArgs e)
{
firstInt = Convert.ToInt32(textBoxInput.Text);
Operator = "-";
textBoxInput.Text += (" - ");
}
private void button12_Click(object sender, EventArgs e)
{
firstInt = Convert.ToInt32(textBoxInput.Text);
Operator = "/";
textBoxInput.Text += (" / ");
}
private void button10_Click_1(object sender, EventArgs e)
{
textBoxInput.Text += (".");
}
}
}
Basically, you can't use int.Parse by itself here. You are going to need to do a character-by-character inspection of the code and decide for yourself whether each piece is part of a value vs an operator - essentially building an AST. Then compute the AST using whichever precedence rules your calculator implements.
Try changing this line:
secondInt = int.Parse(textBoxInput.Text);
to this:
secondInt = int.Parse(textBoxInput.Text.Split('/', '+', '-', '*')[1].Trim());
And see if it helps.
I tried to simply answer the question, not delve into details of making a solid calculator application since the topic is too broad.
You can use Mathematical Expressions Evaluator for .NET e.g: NCalc
Expression e = new Expression("2 + 3 * 5");
Debug.Assert(17 == e.Evaluate());
For your case
Expression e = new Expression(textBoxInput.Text);
labelResult.Text = e.Evaluate().ToString();
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
The calculator works fine if I keep using the same operator(*, /, +, -) but if for example I decide to multiply the total of two added numbers it'll give me a wrong answer. I've looked for a solution but can't seem to find one.
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
bool multiply = false;
bool divide = false;
bool add = false;
bool subtract = false;
private void btnOne_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + "1";
}
private void btnTwo_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + "2";
}
private void btnThree_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + "3";
}
private void btnFour_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + "4";
}
private void btnFive_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + "5";
}
private void btnSix_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + "6";
}
private void btnSeven_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + "7";
}
private void btnEight_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + "8";
}
private void btnNine_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + "9";
}
private void btnZero_Click(object sender, EventArgs e)
{
if (txtDisplay.Text.Length > 0)
{
txtDisplay.Text = txtDisplay.Text + "0";
}
}
private void btnClear_Click(object sender, EventArgs e)
{
txtDisplay.Clear();
}
private void btnDecimalPoint_Click(object sender, EventArgs e)
{
if (txtDisplay.Text.Contains("."))
{
return;
}
else
{
txtDisplay.Text = txtDisplay.Text + ".";
}
}
private void btnNegative_Click(object sender, EventArgs e)
{
if (txtDisplay.Text.Contains("-"))
{
txtDisplay.Text = txtDisplay.Text.Remove(0,1);
}
else
{
txtDisplay.Text = "-" + txtDisplay.Text;
}
}
private void btnMultiply_Click(object sender, EventArgs e)
{
if (txtDisplay.Text == "")
{
return;
}
else
{
multiply = true;
txtDisplay.Tag = txtDisplay.Text;
txtDisplay.Text = "";
}
}
private void btnAdd_Click(object sender, EventArgs e)
{
if (txtDisplay.Text == "")
{
return;
}
else
{
add = true;
txtDisplay.Tag = txtDisplay.Text;
txtDisplay.Text = "";
}
}
private void btnSubtract_Click(object sender, EventArgs e)
{
if (txtDisplay.Text == "")
{
return;
}
else
{
subtract = true;
txtDisplay.Tag = txtDisplay.Text;
txtDisplay.Text = "";
}
}
private void btnEquals_Click(object sender, EventArgs e)
{
if (multiply)
{
decimal dec = Convert.ToDecimal(txtDisplay.Tag) * Convert.ToDecimal(txtDisplay.Text);
txtDisplay.Text = dec.ToString();
}
if (divide)
{
decimal dec = Convert.ToDecimal(txtDisplay.Tag) / Convert.ToDecimal(txtDisplay.Text);
txtDisplay.Text = dec.ToString();
}
if (add)
{
decimal dec = Convert.ToDecimal(txtDisplay.Tag) + Convert.ToDecimal(txtDisplay.Text);
txtDisplay.Text = dec.ToString();
}
if (subtract)
{
decimal dec = Convert.ToDecimal(txtDisplay.Tag) - Convert.ToDecimal(txtDisplay.Text);
txtDisplay.Text = dec.ToString();
}
else
{
return;
}
}
private void btnDivide_Click(object sender, EventArgs e)
{
if (txtDisplay.Text == "")
{
return;
}
else
{
divide = true;
txtDisplay.Tag = txtDisplay.Text;
txtDisplay.Text = "";
}
}
}
It looks like the problem is that you aren't clearing your operation commands. i.e. you set it to Add, but you never clear the Add when you set it to Multiply. If you look in the btnEquals_Click method, it's possible to have several operations active at once, and it will execute all of them.
Look at your btnEquals_Click event. Someone chooses to add, so add = true and it's the only if block that executes - everything good so far.
Then someone chooses to multiply, so now multiply = true, but add = true as well, so now you're multiplying and adding. If someone goes through all the operators, then (because you're never clearing your operator flags), every number thereafter will be multiplied, then divided, then added, and finally subtracted.
To fix it, you could create a method that clears the operators:
private void ResetOperatorFlags()
{
multiply = false;
divide = false;
add = false;
subtract = false;
}
Then call it before you perform an operation on the number:
private void btnMultiply_Click(object sender, EventArgs e)
{
if (txtDisplay.Text == "")
return;
ResetOperatorFlags();
multiply = true;
txtDisplay.Tag = txtDisplay.Text;
txtDisplay.Text = "";
}
Finally, in your btnEquals_Click event, use else if... you won't really need it after clearing the flags, but there's no sense in testing every flag if only one can be set at a time:
private void btnEquals_Click(object sender, EventArgs e)
{
if (multiply)
{
...
}
else if (divide)
{
...
I'm trying to write a caculator as a website,
I set 2 variables in my class to store the number,
but everytime I click a "+" or "-" button,
the variable go back to the inital stamtement.
Here is my code:
public partial class _Default : System.Web.UI.Page
{
int choice = 0;
Boolean caluOrNot = false;
double before, after;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Btn1_Click(object sender, EventArgs e)
{
if (this.caluOrNot == false)
{
if (txtResult.Text.ToString() == "0")
{
txtResult.Text = "1";
}
else
{
txtResult.Text += "1";
}
}
else
{
txtResult.Text = "1";
}
}
protected void Btn2_Click(object sender, EventArgs e)
protected void Btn3_Click(object sender, EventArgs e)
protected void Btn4_Click(object sender, EventArgs e)
protected void Btn5_Click(object sender, EventArgs e)
protected void Btn6_Click(object sender, EventArgs e)
protected void Btn7_Click(object sender, EventArgs e)
protected void Btn8_Click(object sender, EventArgs e)
protected void Btn9_Click(object sender, EventArgs e)
protected void Btn0_Click(object sender, EventArgs e)
protected void BtnPoint_Click(object sender, EventArgs e)
{
txtResult.Text += ".";
}
protected void BtnJia_Click(object sender, EventArgs e)
{
this.choice = 1;
this.caluOrNot = true;
before = Double.Parse(txtResult.Text.ToString());
txtCalu.Text = before.ToString() + "+";
}
protected void BtnJen_Click(object sender, EventArgs e)
protected void BtnCheng_Click(object sender, EventArgs e)
protected void BtnChu_Click(object sender, EventArgs e)
protected void btnClear_Click(object sender, EventArgs e)
{
txtResult.Text = "0";
this.choice = 0;
}
protected void btnGo_Click(object sender, EventArgs e)
{
double a;
switch (this.choice)
{
case 1:
a = before + after;
txtResult.Text = a.ToString();
break;
case 2:
a = before - after;
txtResult.Text = a.ToString();
break;
case 3:
a = before * after;
txtResult.Text = a.ToString();
break;
case 4:
a = before / after;
txtResult.Text = a.ToString();
break;
default:
break;
}
}
}
As th code, everytime I click btnJia will trigger the onclick method BtnJia_Click
The choice will be set to "1" and caculOrNot set to true, but the values change back to 0 and false when the BtnJia_Click finish.
How can I solve it?
In ASP.NET when you click BtnJia_Click everything starts from beginning. So you need to store values of caculOrNot and choice at session and read them from session when you need them. Here is an example:
protected void BtnJia_Click(object sender, EventArgs e)
{
this.choice = 1;
this.caluOrNot = true;
before = Double.Parse(txtResult.Text.ToString());
txtCalu.Text = before.ToString() + "+";
//Store them in Session
Session["choice"] = this.choice;
Session["caluOrNot"] = this.caluOrNot;
}
protected void btnGo_Click(object sender, EventArgs e)
{
// Read them from Session when you need
if(Session["choice"] != null)
{
this.choice = Convert.ToInt32(Session["choice"]);
}
double a;
switch (this.choice)
{
case 1:
a = before + after;
txtResult.Text = a.ToString();
break;
case 2:
a = before - after;
txtResult.Text = a.ToString();
break;
case 3:
a = before * after;
txtResult.Text = a.ToString();
break;
case 4:
a = before / after;
txtResult.Text = a.ToString();
break;
default:
break;
}
}
}
Read more about Session State here.
I have been following the C# tutorial at http://www.homeandlearn.co.uk/csharp/csharp_s2p17.html to make a calculator. I was doing just fine, following the instructions verbatim. I think they have to have an error in the tutorial or something because I have been pulling my freaking hair out trying to figure out why my calculator won't clear text when the + sign is clicked, (which, according to his tutorial, it's supposed to do -- right?)
Here is my code (Note the very bottom when I start to call the double variables, as this is where I "got lost"):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Calculator
{
public partial class calc : Form
{
public calc()
{
InitializeComponent();
}
private void btnOne_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + btnOne.Text;
}
private void btnTwo_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + btnTwo.Text;
}
private void btnThree_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + btnThree.Text;
}
private void btnFour_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + btnFour.Text;
}
private void btnFive_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + btnFive.Text;
}
private void btnSix_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + btnSix.Text;
}
private void btnSeven_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + btnSeven.Text;
}
private void btnEight_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + btnEight.Text;
}
private void btnNine_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + btnNine.Text;
}
private void btnZero_Click(object sender, EventArgs e)
{
txtDisplay.Text = txtDisplay.Text + btnZero.Text;
}
private void btnClear_Click(object sender, EventArgs e)
{
txtDisplay.Clear();
}
double total1 = 0;
double total2 = 0;
private void btnPlus_Click(object sender, EventArgs e)
{
total1 = total1 + double.Parse(txtDisplay.Text);
txtDisplay.Clear();
}
private void btnEquals_Click(object sender, EventArgs e)
{
total2 = total1 + double.Parse(txtDisplay.Text);
txtDisplay.Text = total2.ToString();
total1 = 0;
}
}
}
Now, on the next page of the tutorial (http://www.homeandlearn.co.uk/csharp/csharp_s2p18.html), it asks me to add in the code for the equal button. It doesn't do anything it should when I run it. Namely, the textDisplay doesn't clear whatsoever when I hit the btnPlus button.
And I went through a lot of other questions attempting to find an answer before posting this. And no, this is not homework. It's a hobby actually.
I'm going crazy guys. Thanks in advance for any help you may be able to give me. I'm sure when this is figured out I'm going to want to slap myself.
In short: I would advice to look at debugging tool in Visual Studio. It will help you to understand what is going on when you click the buttons.
Here is a good and simple post to look - debugging tutorial
ReWrite the button again,then double click the buttoun from your form,after that try again to press + and see ,think will be sucesfull,wish you good luck
private void btnPlus_Click(object sender, EventArgs e)
{
total1 += total1 + double.Parse(txtDisplay.Text);
txtDisplay.Clear();
}
Just add a "+" before the "=" sign, and it will work.