Reputation: 19
Sometimes it works like 2+2*2 = 6 but when 5*5*5=only 25 here s the code dont really know where the mistake is if someone could help couse i am only a begginer i am using 2 lists to store numbers and operations
namespace kalkulator
{
public partial class Form1 : Form
{
List<double> vnos = new List<double>();
List<char> operacije = new List<char>();
public Form1()
{
InitializeComponent();
reset();
}
private void button_Click(object sender, EventArgs e)
{
Button vnos = (Button)sender;
if (textBox1.Text == "0" && textBox1.Text != null)
textBox1.Text = vnos.Text;
else
textBox1.Text += vnos.Text;
}
private void operacija_Click(object sender, EventArgs e)
{
try
{
vnos.Add(Convert.ToDouble(textBox1.Text));
vse.Text = vse.Text + textBox1.Text;
textBox1.Text = "";
Button button = (Button)sender;
char gumb = Convert.ToChar(button.Text);
switch (gumb)
{
case '+':
operacije.Add('+');
vse.Text = vse.Text + '+';
break;
case '-':
operacije.Add('-');
vse.Text = vse.Text + '-';
break;
case '*':
operacije.Add('*');
vse.Text = vse.Text + '*';
break;
case '/':
operacije.Add('/');
vse.Text = vse.Text + '/';
break;
}
}
catch(FormatException)
{
MessageBox.Show("Napačni format");
}
catch (OverflowException)
{
MessageBox.Show("Preveliko število");
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void clear_Click(object sender, EventArgs e)
{
reset();
}
private void reset()
{
vse.Text = "";
textBox1.Text = "";
vnos.Clear();
operacije.Clear();
}
private void enter_Click(object sender, EventArgs e)
{
try
{
vnos.Add(Convert.ToDouble(textBox1.Text));
vse.Text = vse.Text + textBox1.Text;
textBox1.Text = "";
vnos.Add(0);
operacije.Add('.');
for (int i = 0; i < vnos.Count - 1; i++)
{
if (operacije[i] == '*')
{
vnos[i] = vnos[i] * vnos[i + 1];
vnos.RemoveAt(i + 1);
operacije.RemoveAt(i);
}
else if (operacije[i] == '/')
{
vnos[i] = vnos[i] / vnos[i + 1];
vnos.RemoveAt(i + 1);
operacije.RemoveAt(i);
}
}
for (int i = 0; i < vnos.Count - 1; i++)
{
if (operacije[i] == '+')
{
vnos[i] = vnos[i] + vnos[i + 1];
vnos.RemoveAt(i + 1);
operacije.RemoveAt(i);
}
else if (operacije[i] == '-')
{
vnos[i] = vnos[i] - vnos[i + 1];
vnos.RemoveAt(i + 1);
operacije.RemoveAt(i);
}
}
textBox1.Text = Convert.ToString(vnos[0]);
}
catch (FormatException)
{
MessageBox.Show("Napačni format");
}
catch (OverflowException)
{
MessageBox.Show("Preveliko število");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void button10_Click(object sender, EventArgs e)
{
textBox1.Text = textBox1.Text + ',';
}
}
}
Upvotes: 3
Views: 112
Reputation: 3750
Although I agree that this could not be the best way to implement the calculator, I think I found why your code doesn't compute the correct results with what you have at the moment.
In this specific case the issue is related to the way you handle the operators and operands. As this is one of the most common mistakes we make when dealing with loops and collections I'll answer so you can move forward with your code and hopefully learn something in the process. :-)
Take a look at this snippet copied from your enter_Click(object sender, EventArgs e)
event handler:
for (int i = 0; i < vnos.Count - 1; i++)
{
if (operacije[i] == '*')
{
vnos[i] = vnos[i] * vnos[i + 1];
vnos.RemoveAt(i + 1);
operacije.RemoveAt(i);
}
else if (operacije[i] == '/')
{
vnos[i] = vnos[i] / vnos[i + 1];
vnos.RemoveAt(i + 1);
operacije.RemoveAt(i);
}
}
The issue with this code is that you're consuming the first token in the operations and the operands arrays and then you're removing them from the array. But the thing is that when you do that, the loop control variable (i) is incremented by the for loop (i++) so you're effectively losing one element to consume.
Let me see if I can illustrate this a little bit:
let's say you clicked the following buttons 5 * 5 * 5 =
in that order in your UI. At this point you have:
vnos = [5,5,5,0]
operacije = ['*', '*', '.']
Then you start looping to compute the result. I've removed all the code, left only the relevant bits and written what's happening to your variables step by step below:
for (int i = 0; i < vnos.Count - 1; i++)
{
if (operacije[i] == '*')
{
vnos[i] = vnos[i] * vnos[i + 1];
vnos.RemoveAt(i + 1);
operacije.RemoveAt(i);
}
}
i
is set to 0
.0 < 4
-> true as vnos.Count = 4
. Enter loop blockif (operacije[i] == '*')
is evaluated to true as the first operation is '*'
vnos = [25,5,5,0]
vnos
array -> vnos = [25,5,0]
operacije
array -> operacije = ['*', '.']
1 < 3
-> true as vnos.Count = 3. Enter loop block Condition if (operacije[i] == '*')
is evaluated to false
because i = 1
and the operation in that index is not '*'
but your final delimiter (the dot '.'
) character. Actually the solution is not so complex. You just need to decrement the loop control variable after removing the element from the collection. And thus you're tricking the loop because when the increment step is executed, the variable will be pointing at the correct index this time because you manually decremented before.
So for your case, please note that just by adding a decrement operator at the line where you remove the operation from the list is enough. The change is in the line operacije.RemoveAt(i--);
.
for (int i = 0; i < vnos.Count - 1; i++)
{
if (operacije[i] == '*')
{
vnos[i] = vnos[i] * vnos[i + 1];
vnos.RemoveAt(i + 1);
operacije.RemoveAt(i--); //<----- i-- instead of i.
}
}
Please note you must do this change in all your blocks. That is in all the places you remove from the operation list.
Hope this helps!
Upvotes: 3