Add three numbers with textBox - c#

I have a textbox1 two and three. In textbox1 number zero, in two number one and in three number two and use this code
textBox4.Text = "" +
(int.Parse(textBox1.Text) +
(int.Parse(textBox2.Text +
(int.Parse(textBox3.Text)))));
but result is 012..you can have the entire amount, 3?

int result =
int.Parse(textBox1.Text) +
int.Parse(textBox2.Text) +
int.Parse(textBox3.Text);
textBox4.Text = result.ToString();
Try this

What's happening here is that the sum is being evaluated from left to right and this is causing a different type of addition to be performed than what you would expect. In C#, you can add two strings. If you add "foo" to "bar" then this will give you the string "foobar". If you add a string and a number together, then it will convert the number to a string and add the two strings together. So "foo"+13 yields "foo13".
So what's happening in your example is quite complicated. Starting from the inside, you have: int.Parse(textBox3.Text). This takes textBox3.Text which is "2" and converts it to the number 2. Next you do textBox2.Text + (int.Parse(textBox3.Text) which gets the string "1" and then adds the number 2 to it. This causes the number 2 to be converted to the string "2" and then adds "1"+"2", giving the string "12" as the answer since strings are added by joining them. Next you do int.Parse(textBox2.Text + (int.Parse(textBox3.Text)) which converts the string "12" to the number 12. You also do int.Parse(textBox1.Text) which gives the number 0. So at this point you're adding "" + 0 + 12. It does this from left to right, first adding "" to 0. This causes 0 to be converted to "0" and "" + "0" gives "0". Then we are adding "0" + 12. When we do this, 12 gets converted to "12" and "0"+"12" gives "012".
Without making big changes, you could get the correct result just by changing your parentheses. If the numbers were all added together before any of them are added to strings, then you'll get the correct result. We can accomplish this with parentheses.
textBox4 = "" + (int.Parse(textBox1.Text) + int.Parse(textBox2.Text) + int.Parse(textBox3.Text));
In short, it's really important to pay attention to what's happening in what order and what the types are because adding two strings is completely different from adding two numbers.

Put the " mark at the end that way it does the regular math first, then the string conversion.

You can you smth like this:
int sum=int.Parse(textBox1.Text) + int.Parse(textBox2.Text) + int.Parse(textBox3.Text);
textBox4.Text = String.Format("{0}",sum);

You have 2 problems here. The first one is the "" at the beginning. When you do the first +, textBox1.Text is first parsed, then converted to string again by the string concatenating operator. I'd prefer something like this:
textBox4.Text = (int.Parse(textBox1.Text) + int.Parse(textBox2.Text) + int.Parse(textBox3.Text)).ToString();
The second problem (the real one) is the fact that you miss a closing parenthesis after textBox2.Text. In this way you are first concatenating textBox1.Text ("1") and int.Parse(textBox2.Text).ToString() ("2"), and only at this point you parse the result. If the parenthesis were not missing your code would give "3" and not "012"

Related

Add comma in string if boolean is false

I have 3 booleans:
Boat, Plane, Car
And 3 strings:
ReloadBoat, ReloadPlane, ReloadCar
Depending on these booleans, if false, I need to add commas between the strings.
string errorMessage = (Boat? "" : " " + ReloadBoat) + (Plane? "" : (errMessage) + ReloadPlane) + (Car? "" : ", " + ReloadCar);
For the above, the issue I am getting is, if both Boat and Plane are true, I am getting the errorMessage as ", ReloadCar".
I want it to be "ReloadCar" only.
Any idea on how to do this?
Breaking it out makes the code more readable and maintainable. It'll get really hard work to use your bools in the manner you have there. Instead I recommend you put the commas on your error messages as a matter of routine. Concatenate them together and remove any trailing commas:
string err="";
if(boatNeedsReload)
err+="ReloadBoatErrorMessageWithComma, ";
if(planeNeedsReload)
err+="ReloadPlaneErrorMessageWithComma, ";
if(carNeedsReload)
err+="ReloadCarErrorMessageWithoutComma";
err = err.TrimEnd(new[]{' ',','});
So the method is:
Put punctuation between all your elements regardless
Trim off trailing redundant punctuation as the last operation
I didn't put any punctuation after ReloadCar because as the last item, it isn't strictly necessary. If this were extended in future to add another item at the end you'd have to remember to punctuate ReloadCar. You might thus wish to consider punctuating car right now and not have to remember to do it next time
If you use a stringbuilder you can interrogate the length and knock 2 off it if needs be:
StringBuilder err=new StringBuilder();
if(boat)
err.Append("ReloadBoat, ");
if(plane)
err.Append("ReloadPlane, ");
if(car)
err.Append("ReloadCar, ");
if(err.Length>0);
err.Length-=2;
this time I did punctuate reloadcar because this method wouldn't work properly without it
Don't try to do too much on one line in your code; you'll reach a point where it needs modifying in a months time and it'll take longer to work out how it works and how to extend it than just breaking it out to something readable and hence maintainable
As an example, this does the same as the first code block, but it's a bit "what the..?"
string err = (
(boatNeedsReload ? "ReloadBoatErrorMessageWithComma, ":"")+
(planeNeedsReload ? "ReloadPlaneErrorMessageWithComma, ":"")+
(carNeedsReload ? "ReloadCarErrorMessageWithoutComma":""))
.TrimEnd(new[]{' ',','});
Falco makes a good point, that you should strive to make your Boolean variables have a name that declares a truth, like "isTooYoung" or "boatNeedsReload". Make your Boolean have a positive spirit, as it starts to get confusing if you write if(boatDoesntNeedReload==false). Note also that classic advice is to not compare a Boolean with another Boolean to realise a Boolean, but consider that comparing with false can make code more readable than using ! to invert a truth
I would create a list of strings with errors and appended to it based on the bools and string join them with a comma or whatever you want.
var boatErrorMessage = "boatErrorMessage";
var planeErrorMessage = "planeErrorMessage ";
var carErrorMessage = "carErrorMessage";
var isBoat = true;
var isPlane = false;
var isCar = true;
var errorMessageList = new List<string>();
if (isBoat)
errorMessageList.Add(boatErrorMessage);
if (isPlane)
errorMessageList.Add(planeErrorMessage);
if (isCar)
errorMessageList.Add(carErrorMessage);
Console.WriteLine(string.Join(", ", errorMessageList));
Output: boatErrorMessage, carErrorMessage

How to slice/trim this value?

I am trying to remove the last 6 characters from item.Size because the data has a decimal place and 5 trailing 0s in the database.
sb.Append("<div>" + item.Size + " " + item.Units + " </div>");
ie. item.Size is displayed as 1.00000 and I need it to just be displayed as 1.
This is part of a StringBuilder, and as I'm new to coding, not even sure the right way to go about this.
sb.Append("<div>" + (int)item.Size + " " + item.Units + " </div>");
StringBuilder has the same formatting capabilities as String.Format when you use the AppendFormat method:
sb.AppendFormat("<div>{0:N0} {1} </div>", item.Size, item.Units);
The format string "N0" tells it to format the number with 0 decimal points. That assumes the item.Size is stored as a numerical type. If not, simply remove the part of the string you don't want:
sb.AppendFormat("<div>{0} {1}</div>", item.Size.Split('.')[0], item.Units);
Here I've used Split, assuming that the value is actually something like what you've shown in your example.
Better you use int.TryParse(or Int32.TryParse) method. because if item.Size is not convertible to int, then it wont give you any exception. you can use int or long according to your choice. So you can handle this in your code according to the if/else condition.
Sample Code:
int size;
string str = "";
if(int.TryParse(str, out size) == true)
{
}
else
{
}

String Format with undefined number of characters c#

So I'm working on formatting a string and I need to line it up in a table, but this string has an undetermined number of characters. Is there anyway to have the string be in the same spot for each column? so far I have:
ostring += "Notes\t\t"
+ " : "
+ employees[number].Notes
+ "\t\t"
+ employees[number].FirstNotes
+ "\t\t"
+ employees[number].SecondNotes;
I use a similar fashion on the other rows, but they have a pre-determined number of digits, this however doesn't so I can't use the string modifiers like I would like.
Any ideas on what I need to do?
You can use String.PadRight() to force the string to a specific size, rather than using tabs.
When you are using String.Format item format has following syntax:
{ index[,alignment][ :formatString] }
Thus you can specify alignment which indicates the total length of the field into which the argument is inserted and whether it is right-aligned (a positive integer) or left-aligned (a negative integer).
Also it's better to use StringBuilder to build strings:
var builder = new StringBuilder();
var employee = employees[number];
builder.AppendFormat("Notes {0,20} {1,10} {2,15}",
employee.Notes, employee.FirstNotes, employee.SecondNotes);
You would first have to loop over every entry to find the largest one so you know hoe wide to make the columns, something like:
var notesWidth = employees.Max(Notes.Length);
var firstNotesWidth = employees.Max(FirstNotes.Length);
// etc...
Then you can pad the columns to the correct width:
var output = new StringBuilder();
foreach(var employee in employees)
{
output.Append(employee.Notes.PadRight(notesWidth+1));
output.Append(employee.FirstNotes.PadRight(firstNotesWidth+1));
// etc...
}
And please don't do a lot of string "adding" ("1" + "2" + "3" + ...) in a loop. Use a StringBuilder instead. It is much more efficient.

Linq why does concatenating strings result in a null?

I thought that "bill" + "john" + null == billjohn, but in this example of mine it seems to be evaluating to null:
var clients = from client in taxPortalService.Client()
select new ClientViewModel
{
ResidentialAddressLine1 = client.RESADDRESSLINE1,
ResidentialAddressLine2 = client.RESADDRESSLINE2,
ResidentialAddressLine3 = client.RESADDRESSLINE3,
ResidentialAddressLine4 = client.RESADDRESSLINE4,
ResidentialPostalCode = client.RESPOSTCODE,
ResidentialCountry = client.RESCOUNTRY,
IAResidentialAddress = client.RESADDRESSLINE1 + ", " + client.RESADDRESSLINE2 + ", " + client.RESADDRESSLINE3 + ", " + client.RESADDRESSLINE4 + ", " + client.RESPOSTCODE + ", " + client.RESCOUNTRY
};
Am I missing something obvious here?
I'm guessing this is using LINQ-to-SQL or EF as a backend, and it is generating SQL. Well, in TSQL a null concatenated with anything is (by default): null. Perhaps try:
(row.Foo ?? "") + ", " + (row.Bar ?? "") + ...
or easier: get the data as values into memory first, then do compositions.
In C#, or rather in .NET, you're right, "bill" + "john" + null gives you "billjohn".
In SQL, 'bill' + 'john' + null gives you null.
Using LINQ to Entities translates your C# to SQL, and subtle differences such as this aren't always preserved.
You can use the more verbose
(client.RESADDRESSLINE1 ?? "") + ", " + (client.RESADDRESSLINE2 ?? "") + ", " + ...
to make sure you only concatenate non-null strings, which won't have this problem.
Assuming SQL-Server as rdbms, a quick test reveals:
select 'A' + NULL; // NULL
Demo
MSDN
The + (String Concatenation) operator behaves differently when it
works with an empty, zero-length string than when it works with NULL,
or unknown values. A zero-length character string can be specified as
two single quotation marks without any characters inside the quotation
marks. A zero-length binary string can be specified as 0x without any
byte values specified in the hexadecimal constant. Concatenating a
zero-length string always concatenates the two specified strings. When
you work with strings with a null value, the result of the
concatenation depends on the session settings. Just like arithmetic
operations that are performed on null values, when a null value is
added to a known value the result is typically an unknown value, a
string concatenation operation that is performed with a null value
should also produce a null result. However, you can change this
behavior by changing the setting of CONCAT_NULL_YIELDS_NULL for the
current session. For more information, see SET CONCAT_NULL_YIELDS_NULL
(Transact-SQL). If the result of the concatenation of strings exceeds
the limit of 8,000 bytes, the result is truncated. However, if at
least one of the strings concatenated is a large value type,
truncation does not occur.

How does the C# compiler work with a split?

I have an List<string> that I am iterating through and splitting on each item then adding it to a StringBuilder.
foreach(string part in List)
{
StringBuilder.Append(part.Split(':')[1] + " ");
}
So my question is how many strings are created by doing this split? All of the splits are going to produce two items. So... I was thinking that it will create a string[2] and then an empty string. But, does it then create the concatenation of the string[1] + " " and then add it to the StringBuilder or is this optimized?
The code is actually equivalent to this:
foreach(string part in myList)
{
sb.Append(string.Concat(part.Split(':')[1], " "));
}
So yes, an additional string, representing the concatenation of the second part of the split and the empty string will be created.
Including the original string, you also have the two created by the call to Split(), and a reference to the literal string " ", which will be loaded from the assembly metadata.
You can save yourself the call to Concat() by just Appending the split result and the empty string sequentially:
sb.Append(part.Split(':')[1]).Append(" ");
Note that if you are only using string literals, then the compiler will make one optimzation for you:
sb.Append("This is " + "one string");
is actually compiled to
sb.Append("This is one string");
3 extra strings for every item
part[0];
part[1];
part[1] + " "
the least allocations possible would be to avoid all the temporary allocations completely, but the usual micro-optimization caveats apply.
var start = part.IndexOf(':') + 1;
stringbuilder.Append(part, start, part.Length-start).Append(' ');
You have the original string 'split' - 1 string
You have the 'split' split into two - 2 string
You have the two parts of split joined - 1 string
The string builder does not create a new string.
The current code uses 4 strings, including the original.
If you want to save one string do:
StringBuilder.Append(part.Split(':')[1]);
StringBuilder.Append(" ");
This code:
foreach(string part in List)
{
StringBuilder.Append(part.Split(':')[1] + " ");
}
Is equivalent to:
foreach(string part in List)
{
string tmp = string.Concat(part.Split(':')[1], " ");
StringBuilder.Append(tmp);
}
So yes, it's creating a string needlessly. This would be better, at least in terms of the number of strings generated:
foreach(string part in List)
{
StringBuilder.Append(part.Split(':')[1])
.Append(" ");
}
So for each value in the list (n, known as part in your code) you are allocating:
x (I assume 2) strings for the split.
n strings for the concatenation.
Roughly n + 1 string for the StringBuilder; probably much less though.
So you have nx + n + n + 1 at the end, and assuming the split always results in two values 4n + 1.
One way to improve this would be:
foreach(string part in List)
{
var val = part.Split(':')[1];
StringBuilder.EnsureCapacity(StringBuilder.Length + val.Length + 1);
StringBuilder.Append(val);
StringBuilder.Append(' ');
}
This makes it 3n + 1. It is a rough estimate as StringBuilder allocates strings as it runs out of space - but if you EnsureCapacity you will prevent it from getting it wrong.
Probably the only way to be sure about how this is compiled is to build it and decompile it again with Refactor to see how it's internally handled. Anyway have in mind that probably it does not have impact on the whole app performance.

Categories

Resources