I am new to c# programming and I recently bumped into one problem which looks pretty basic.I store the string value like SV_1 in the variable lastServiceNo and split it using Split function and the result is stored in string array called index.Basically index[1] has some numeric value bt as string. now I want to convert string into int. In the following code , it behaves as expected until parse function is encountered.I could not understand why does this parse function returning 0 as index[1] has some numeric value in it. Can somebody point the problem please??
public string GenerateServiceNo() {
DataAccessLayer.DataAccessLayer dlObj= new DataAccessLayer.DataAccessLayer();
string lastServiceNo = dlObj.GetLastServiceNo();
string[] index = lastServiceNo.Split('_');
int lastIndex = int.Parse(index[1]);
return "SV_"+(lastIndex++).ToString();
}
int.Parse(string s) throws an exception if the number is too bug in terms of data size or the string "s" is not in the correct numerical format.
The format that this method accepts is "[ws][sign]number[ws]" where:
[ws] is optional for one or more whitespace(" ")
[sign] is optional for "+" or "-"
Check here for the full reference.
Thus said, I can assure you that if int.Parse(index[1]) returns 0 then that means index[1] equals "[ws][sign]0[ws]" using the transcript above.
However, looking at your code, I can conclude that you're incrementing a local variable after assignment without using its incremented value afterwards. Perhaps you meant that this operation shouldn't be 0?
If that's the case then I believe this is what you're trying to achieve:
public string GenerateServiceNo()
{
DataAccessLayer.DataAccessLayer dlObj= new DataAccessLayer.DataAccessLayer();
string lastServiceNo = dlObj.GetLastServiceNo();
string[] index = lastServiceNo.Split('_');
int lastIndex = int.Parse(index[1]);
return string.Format("SV_{0}", ++lastIndex);
}
Assuming index[1] == "0", this method will now return "SV_1".
Related
I’m working on a self directed simple program to practice concepts I’ve learned thus far. My project is related to chess, in this case specifically the board (columns a-h and rows 1-8). The user is asked for the current location of a specific chess piece hopefully entered as a letter for the column followed by a number for the row.
To validate this it made sense to me to first check if this value was entered as a string of two characters, otherwise what is entered is already incorrect.
I then converted the entered string to lower case characters before comparing it with my list of acceptable array elements.
From searching this site I get the impression that a string stores its characters as an array and using the char property of string you would be able to pull off the first character thus comparing char to char. I have not yet found anything specific enough in my searches to really give me a good understanding of what is happening. This is the closest option I’ve come across which I didn’t feel was applicable to this case. Any insight would be appreciated.
The code that follows produces the following error.
Operator ‘==’ cannot be applied to operands of type ‘char’ and
‘string’
private char[] gridColumns = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', };
private void createMoveButton_Click(object sender, RoutedEventArgs e)
{
// Assigns text box input to associated private fields
this.gameId = this.gameIdTextBox.Text;
this.playerId = this.playerIdTextBox.Text;
this.gamePiece = this.gamePieceTextBox.Text;
this.currentLocation = this.currentLocationTextBox.Text;
this.targetLocation = this.targetLocationTextBox.Text;
// Current location should only ever be 2 characters, ensure from the start this is true.
if (currentLocationTextBox.Text.Length == 2)
{
// Converts contents of currentLocationTextBox to lower case characters for comparison.
string cl = currentLocation.ToLowerInvariant();
// Iterates through my array of possible column choices
for (int i = 0; i < gridColumns.Length; i++)
{
Char.ToLowerInvariant(currentLocationTextBox.Text[0]);
// Trying to compare the first character of my string to the char element of my array.
if (cl[0] == gridColumns[i])
{
//TODO
}
}
}
else
{
MessageBox.Show("Check your starting location. It needs to be a lower case character variable (a-h) followed by a number (1-8)");
}
}
Unlike C, a string and an array of char are different. A string in C# can be viewed as an array of char but you should consider them different, therefore the '==' comparison isn't appropriate. One easy way to see this is with the following simple expression
if ("a" == 'a') { /* do something */ } // ERROR!
It looks like it should work but it generates the same error you are seeing, because it is trying to compare the string "a" to the char 'a'. In your example code the Text property of your textbox control is of type string.
The string class has an indexer that allows you to treat a string as an array of char, but it's usually better (simpler) to use one of the many string methods to accomplish your goal. Consider this:
var gridcolumns = "abcdefgh";
var gridrows = "12345678";
var input = "a1"; // column row
var col = gridcolumns.IndexOf(input[0]); // 0 -7
var row = gridrows.IndexOf(input[1]); // 0 -7
In the code you gave I don't see a line that would generate the error you provided. The following line serves no purpose
Char.ToLowerInvariant(currentLocationTextBox.Text[0]);
Because you are not assigning the returned value to a variable, plus 'cl' already contains the lowercasing of that particular value.
This line
if (cl[0] == gridColumns[i])
should not generate the error because both items are of type char.
Dweeberly's answer when applied... and shortened:
Answer: Change the single quotes to double-quotes.
My reasoning:
Assume the following code:
string IAmAString;
// set string to anything
IAmAString = "Q";
if (IAmAString == 'Q')
{
// do something, but never gets here because "Q" is a string, and 'Q' is a char
// Intellisense gives error on the if statement of
//
// "Operator '==' cannot be applied to operands of types 'string' and 'char'"
//
// because C# is a strongly typed language, and the '==' is not by
// default (in VS2012) overloaded to compare these two different types.
// You are trying to compare a string with something that
// is not-string, and C# is trying to let you know
// that that is not going to work.
}
It is fixed by changing the quotes to double-quotes. C# definitely seems to consider single quotes around a single character to be Char, and not string.
just change the quotes within the if statement:
IAmAString = "Q";
if (IAmAString == "Q")
{
// does whatever is here within reason; "Q" is a string and "Q" is a string
}
At least this worked for me, and that's my 'quick' (where 'q' != "q") explanation of why.
Getting back to work...
Try to use this comparison:
(cl.ToCharArray())[0] == gridColumns[i]
I ran your program and it works fine. I think problem is some place else.
Looping through the array just to see if an element is contained in it is kind of overkill when an array has a .Contains method. Something like this without the for loop should work:
if (gridColumns.Contains(cl[0]))
{
//TODO
}
if(char[0].ToString() == "!") print("do something");
I am working on a file parser, and this bit of code is not giving me what I want. Before I go any farther, I should mention that I did not write this program, I am only editing the source to fix this specific problem. Also, I can compile the code, so that is not a problem (you know how downloaded programs always have compile errors). Here's the code.
case EsfValueType.Binary4E: //System.String[]
{
int size = (int)(this.reader.ReadUInt32() - ((uint)this.reader.BaseStream.Position));
var strings = new string[size / 4];
for (int i = 0; i < size / 4; i++)
strings[i] = this.stringValuesUTF16[this.reader.ReadUInt32()];
esfValue.Value = strings.ToString();
break;
}
Now, I added the .ToString(); part to the above line, but it made no difference. The problem is that esfValue.Value ends up with System.String[] as it's value, and I want the value of the System.String object. If you can make sense out of this and tell me what is wrong, it would be appreciated.
The program name is ESF Editor 1.4.8.0.
case EsfValueType.Binary4E: //System.String[]
{
int size = (int)(this.reader.ReadUInt32() - ((uint)this.reader.BaseStream.Position));
var strings = new StringBuilder();
for (int i = 0; i < size / 4; i++)
{
strings.Append(this.stringValuesUTF16[this.reader.ReadUInt32()]); //or AppendLine, depending on what you need
}
esfValue.Value = strings.ToString();
break;
}
The strings variable is an array of strings - the Array class does not override the default ToString() implementation which returns the type of the object.
You need to concatenate all the strings in the array - either looping and concatenating or using LINQ and assign the resulting string to esfValue.Value. Of course, this assumes you want the values all in one string, one after the other.
Your issue is that strings isn't a single string, its an array of strings. As a result your call to ToString is calling Object.ToString(), which returns the type of the object.
Maybe you want something like
esfValue.Value = strings.Aggregate((acc, next) => acc + next)
which will simply concatenate all the strings together.
When you do a .ToString() on a class that doesn't override the .ToString() base method to return a custom string (which string[] doesn't), you're always going to get the type's namespace/class as the result.
Arrays, in and of themselves, don't have values. What value are you trying to get? Are you trying to join the array into a single, character-delimited string? If so, this would work:
esfValue.Value = string.Join(",", strings);
Just replace the , with whatever character you want to delimit the array with.
I think you just need to join the string values contained in the string array. In order to do so, you need to call String.Join and pass the string separator and the string array. It returns a single System.String.
string nr = "42245555" //just an example number
string expression = "{5}{6}/{7}{8}";
string res = String.Format(expression, new string[] {
nr[0].ToString(),nr[1].ToString(),
nr[2].ToString(), nr[3].ToString(),
nr[4].ToString(), nr[5].ToString(),
nr[6].ToString(), nr[7].ToString()
});
Why is this not working and how can I solve it?
I want expression to be either "{5}{6}/{7}{8}" or "{0}{3}/{7}{1}" or whatever the user wants.
You must supply at least the same number of parameters (or an array with at least the same number of elements) as the highest placeholder value plus one (placeholder values are zero indexed)
Max placeholder value {3}, you must supply at least four additional parameters.
Try this:
string res = String.Format(expression,
nr[0], nr[1],
nr[2], nr[3],
nr[4], nr[5],
nr[6], nr[7]);
Note that I took out new string[] { ... } I also took out all the ToString() because they are not required.
The relevant overload of Format is:
public static string Format(string format, params Object[] args)
This means you can either call it like this:
Format("...",new object[]{...})//Each array element is used
Or with the objects directly as parameters:
Format("...",object1, object2,...)//the objects are used
Unlike what I originally thought, a string[] does indeed go into the first variant of this code. This is due to array covariance in C#/.net which allows a string[] to be implicitly converted to a object[].
string.Format("{0} {1}",new string[]{"A","B"})
prints A B.
On the other hand if you try similar code with a int[] it won't work:
string.Format("{0} {1}",new int[]{1,2})
Will throw an exception because it goes into the second variation, and thus only a single parameter of type int[] is seen by string.Format. This difference is because array covariance only works on arrays with members that are a reference type like string and not a value type like int. This means int[] is not implicitly convertible to object[].
So the problem with your original code is probably just that you used the index {8} which is out of range.
The parameters in expression must start from "{0}" and the array must contain the same number of parameters as the expression and it must be an array of objects : new object[]{...
Your parameters are numbered 0..7, easy to read back. Yet you use {8} : Index out of Range
You don't need the new string[] { } around the parameters. It is allowed though.
without the new string[] { } you don't need the .ToString() calls either.
IF ur user wants {5}{6}/{7}{8} , then ur code will be:
String.Format("{0}{1}/{2}{3}",nr[4],nr[5],nr[6],nr[7]);
ur indexes in the expression must always start with 0..In my example if u want to display this for strings.. u start by 0,1,2,3.. 0 for nr[4], 1 for nr[5], 2 for nr[6], 3 for nr[7], etc..
You have to use:
nr.Substring(...)
in String.Format([expression], [values]) expression is a string represent a string with placeholders while values are inserted in those placeholders.
updated
string nr = "42245555" //just an example number
string res = String.Format("{0}{1}/{2}{3}", new string[] {
nr[5].ToString(),nr[6].ToString(),
nr[7].ToString(), nr[8].ToString()
});
or
string res = String.Format("{0}{1}/{2}{3}", new string[] {
nr[0].ToString(),nr[3].ToString(),
nr[7].ToString(), nr[1].ToString()
});
I have a method that inputs an integer as a parameter in a class -
public string OddNumbers(int input)
and in my main program, I am trying to accept an integer from the user, through a textbox, and I am converting the input string to integer while passing the parameter -
string odd = od.OddNumbers(int.Parse((TextBox1.Text))).ToString();
and I am getting the following error:
"System.FormatException: Input string was not in a correct format."
I tried different methods of converting the integer to string, but results in the same error, for example:
string odd = od.OddNumbers(Convert.ToInt32(TextBox1.Text));
Any help in pointing out where I am going wrong?
What input are you trying to enter?
I would try a couple of things.
1) Run a trim on the input before passing it into the parse command. This will make sure there are no empty spaces at the end of the number.
2) If you are trying to accept a decimal, make sure you use double.
Do not nest functions, it makes code incredibly difficult do debug and maintain.
int Number;
if (int.TryParse(TextBox1.Text, out Number) == false)
{
// parsing error
Number = -1;
}
string odd = od.OddNumbers(Number);
The following should work assuming that the user enters a valid integer in the textbox:
int i = int.Parse(TextBox1.Text);
string odd = od.OddNumbers(i).ToString();
Another possible way to handle this is to use the TryParse method:
int i;
if (int.TryParse(TextBox1.Text, out i))
{
string odd = od.OddNumbers(i).ToString();
}
else
{
MessageBox.Show(TextBox1.Text + " is not a valid integer");
}
Once i put the method inside an click event, which finds out whether the input integer is odd or even, it gave me the desired result. thanks for all the inputs.
What is the best way to take a string which can be empty or contain "1.2" for example, and convert it to an integer? int.TryParse fails, of course, and I don't want to use float.TryParse and then convert to int.
Solution 1: Convert.ToDouble (culture-dependent)
You may using Convert.ToDouble. But, beware! The below solution will work only when the number separator in the current culture's setting is a period character.
var a = (int)Convert.ToDouble("1.2");
Solution 2: Convert.ToDouble (culture-independent)
It's preferable to use IFormatProvider and convert the number in an independent way from the current culture settings:
var a = (int)Convert.ToDouble("1.2", CultureInfo.InvariantCulture.NumberFormat);
Solution 3: Parse & Split
Another way to accomplish this task is to use Split on parsed string:
var a = int.Parse("1.2".Split('.')[0]);
Or:
var a = int.Parse("1.2".Split('.').First());
Notes
If you want to handle empty and null strings, write a method and add string.IsNullOrEmpty condition.
To get decimal separator for the current culture setting, you can use NumberFormatInfo.NumberDecimalSeparator property.
You should also keep eye on rounding to avoid traps.
Select casting, Parse, TryParse or Convert class wisely. Read more at:
How to: Convert a string to an int (C# Programming Guide)
How to: Determine Whether a String Represents a Numeric Value (C# Programming Guide)
I don't know what's wrong with parsing to a float and converting to an int. I doubt that any other way would be more efficient but here's an attempt:
//allows empty strings and floating point values
int ParseInt(string s, bool alwaysRoundDown = false)
{
//converts null/empty strings to zero
if (string.IsNullOrEmpty(s)) return 0;
if (!s.Contains(".")) return int.Parse(s);
string parts = s.Split(".");
int i = int.Parse(parts[0]);
if (alwaysRoundDown || parts.Length==1) return i;
int digitAfterPoint = int.Parse(parts[1][0]);
return (digitAfterPoint < 5) ? i : i+1;
}
In order to globalize the code you would need to replace "." with System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator.
int a = (int)Math.Round(float.Parse("0.9"));
You need to round it first unless you want 0.9f being converted to 0 instead of 1.
Maybe you can try to delete everything after floating point using string functions and then convert to int. But seriously I don't think it's better than converting to float and then to int.
I think another way of doing it would be splitting the string into pieces taking the decimal (.) as the delimiter and then parsing for the integer. Of course, I am yet to ask you if the string might contain values like "37.56 miles in 32.65 seconds" type values.
Considering there will be only one value (string or number) in the string, I can think of something in the following line:
public int64 GetInt64(string input)
{
if (string.IsNullOrEmpty(input)) return 0;
// Split string on decimal (.)
// ... This will separate all the digits.
//
string[] words = input.Split('.');
return int.Parse(words[0]);
}
You can use the Visual Basic runtime Library to accomplish this from c#.
You need to add a reference to the assembly Microsoft.VisualBasic.dll to your solution.
Then the following code will do your conversion:
using VB = Microsoft.VisualBasic.CompilerServices;
class Program
{
static void Main(string[] args)
{
int i = VB.Conversions.ToInteger("1.2");
}
}
I had this same problem and ended up using a hybrid of Mark's and Dariusz':
if (num == "")
{
num = "0.00";
}
var num1 = (float)Convert.ToDouble(num);