Getting a character from a string is returning an

2019-08-22 05:12发布

问题:

I have a list box that contains the ID number and model of a number of cars, taken from an access table. I have some text boxes that will be filled with the data from that table when a car is selected from the list box. To get the id number of the selected car, I'm using this code:

int idNum = listBox1.SelectedItem.ToString()[0];

Which should get the first character in the item string (it's ID number). When I select the first item in the list, what I am instead getting is 49. My first thought was that I wasn't casting it to an int, so maybe the 49 represents some character code for the number, however

Convert.ToInt16(listBox1.SelectedItem.ToString()[0])

Returns the exact same number. The second item is 50, and so on and so forth.

I want to be changing how I get the ID number from this char conversion anyway, as it's just occurred to me that once I hit 10 cars it won't work, but why am I getting such a large, consistently offset, and (perhaps most bafflingly of all) multi-digit number from a c# equivalent of java's charAt[0]?

The specific error I've been getting is that there is no row at position 49, which pops up when I try to get the value of mydataset.Tables["mytable"].Rows[idNum]["CarID"].ToString();. Now, I can see a few things that could be causing this issue, I have absolutely know idea if Rows[idNum]["CarID"] is the correct syntax, and was very surprised to see that my guess worked, but it's still a very weird problem.

回答1:

You need to get the numeric value for Char:

int idNum = (int)Char.GetNumericValue(listBox1.SelectedItem.ToString()[0]);

While int idNum = listBox1.SelectedItem.ToString()[0]); return the ASCII of Character '1' (example) which is 49.

This is the actual code from Microsoft for Convert.ToInt16:

public static short ToInt16(char value) 
{
    // Some validations
    return (short)value;
}

Convert.ToInt16 for a char does an Explicit conversion, which gets the ASCII for that Character Value.

For Handling Multiple Digits:

string str = "37abcdef";
string myStrNumber  = Regex.Match(str, @"\d+").Value;

int idNum2;

if (myStrNumber.Length > 0)
    idNum2 = Convert.ToInt32(myStrNumber);
else
{
    // Handle Error
}

Or Without using Regex :

string str = "37abcdef";
string myStrNumber = "";

for(int i = 0; i < str.Length; i++)
{
    if (Char.IsNumber(str[i]))
        myStrNumber += str[i];
}

int idNum2;

if (myStrNumber.Length > 0)
    idNum2 = Convert.ToInt32(myStrNumber);
else
{
    // Handle Error
}


回答2:

Try this

int idNum = Convert.ToInt16(listBox1.SelectedItem.ToString()[0].ToString())

because

listBox1.SelectedItem.ToString()[0] return Char. If you convert a Char type data to Integer it will return ASCII of Char. So Convert it into string before converting to Integer ( listBox1.SelectedItem.ToString()[0].ToString() ).



回答3:

user3185569 identified the problem, but I'll put up the solution I ended up using for future reference. The int idNum = listBox1.SelectedItem.ToString()[0]); line was getting the ASCII for the character, 49 for 1, 50 for 2, etc. This can be solved by using (int)Char.GetNumericValue(listBox1.SelectedItem.ToString()[0]) -1;.

(int)Char.GetNumericValue gets the actual number value of that character, rather than the ASCII value. The - 1 is to account for the car ID's starting from 1, but the table indexes start from 0.

This still leaves the issue of digits, if the first character of the string is being used to get the ID number, as soon as there are more than 9 cars, the code won't work. The strings are written in the listbox as "[idNum]: [carName]". For example: 1: Astra. To get the ID number I used Split(':')[0], which splits the string into an array of substrings, splitting at each : character.

The working line of code is:

int idNum = Convert.ToInt16(listBox1.SelectedItem.ToString().Split(':')[0]) - 1;