2

I've tried to solve this for hours and absolutely don't understand what the compiler is doing here. I have strings that basically look like this:

"KL10124 Traitor #2 - +XX-+0.25 - More Stuff"

and need to read off the double '0.25' programmatically. Calling the string above s, the following two lines don't work:

string[] h = s.Split('-');
string h2 = h[2].Substring(1,h[2].Length - 2);
double d = Convert.ToDouble(h2);

The output if I display d is "25". I thought it might depend on the '.' resp ',' culture dependency, but if I insert

double d = Convert.ToDouble(h2.Replace('.',','));

it does not change a thing, the output is still "25".

But finally, if I do the brute force method as below I get the verbatim output "0,25" on the screen

double d;
string[] h = s.Split('-');
string h2 = h[2].Substring(1,h[2].Length - 2);
if (h2.Contains("."))
{
    string[] h3 = h2.Split('.');
    d = Convert.ToDouble(h3[0]) + Convert.ToDouble(h3[1])/100;
}
else
{
    d = Convert.ToDouble(h2);
}
return d;

Why exactly do the first two versions not work? The last bit of code cannot be the correct way to do this.

abatishchev
  • 92,232
  • 78
  • 284
  • 421
EluciusFTW
  • 2,258
  • 6
  • 38
  • 54
  • On the first code, what is `h2`? – CodingGorilla Aug 23 '12 at 13:46
  • 1
    Your first code snippet returns "0.25" when I run it. – LarsTech Aug 23 '12 at 13:47
  • my culture is en-GB and the first bit of code gives me 0.25 – Bob Vale Aug 23 '12 at 13:48
  • Your first example [works perfectly on ideone](http://ideone.com/tsRRe). – Sergey Kalinichenko Aug 23 '12 at 13:49
  • 1
    If the string you are trying to parse has a known structure, why not investigate using the System.Text.RegEx classes to extract the number. – Ben Cawley Aug 23 '12 at 13:49
  • Check this out: http://txt2re.com/index-csharp.php3?s=%22KL10124%20Traitor%20%232%20-%20%2bXX-%2b0.25%20-%20More%20Stuff%22&-7 – froeschli Aug 23 '12 at 13:50
  • While I can't say I like the style employed, there seems to be nothing wrong on the face of it. Have you tried putting in Console.WriteLines between those 3 lines to see what h2 holds (and that there is the expoected number of spits in the h array) etc. – Wolf5370 Aug 23 '12 at 13:56
  • OOps, obv h2 = h. @Wolf5370, this is my beginners ad hoc solution, not claiming it to be good style, just the most obvious code to me. In asking this quetion, I was looking for better ways, so what would your style be? – EluciusFTW Aug 23 '12 at 14:59
  • Well, as pointed out, better to use Double.Parse (or TryParse) with Invariant Culture - However, personally I would use RegEx as it would be easier and faster here I think (and less error prone). However, I'm not a style-cop - just pointing out that the code looks like it should work regardless. Important bit being - it SHOULD work. So, to find out why it isn't, you are going to need to break the code or Console out its progress. I suspect there is a difference in the string than you expect - or the code above is not an absolutely true reflection of the actual code. Good luck. – Wolf5370 Aug 23 '12 at 15:13

8 Answers8

6

Try to use

double d = Convert.ToDouble(h2, CultureInfo.InvariantCulture);

instead of

double d = Convert.ToDouble(h2);
Ilya Ivanov
  • 22,043
  • 4
  • 58
  • 86
  • Thanks, this works. But could you please tell me why my code, even after replacing the '.' with ',' didn't work? – EluciusFTW Aug 23 '12 at 15:04
  • 1
    By default, comma in Convert.ToDouble is used to separate thousandths in number. For example "1,635,555" is Converted into 1635555. Thus, making you number "0,25" just emits number 25. – Ilya Ivanov Aug 23 '12 at 15:43
3

A number of people have already mentioned using Regex. If you are not very familiar with Regex, then this page might help you:

http://txt2re.com/index-csharp.php3?s=%22KL10124%20Traitor%20%232%20-%20%2bXX-%2b0.25%20-%20More%20Stuff%22&-7

Cheers

froeschli
  • 2,444
  • 2
  • 22
  • 47
3

Try the Regex way :

string input = "KL10124 Traitor #2 - +XX-+0.25 - More Stuff";

Match match = Regex.Match(input, "^.*([0-9]+\\.[0-9]+).*$");

if (match.Success)
{
    double value = Convert.ToDouble(match.Groups[1].Value, CultureInfo.InvariantCulture);
    Console.Write(value);
}
Anthony Simmon
  • 1,530
  • 12
  • 23
2
d = double.Parse(h2,CultureInfo.InvariantCulture);

You need to set the format provider of the conversion operation to invariant.

daryal
  • 14,035
  • 4
  • 35
  • 54
  • Thx, this Works, but as in Ivanovs answer, I don't get why my code didn'T work after manually replacing '.' by ',' – EluciusFTW Aug 23 '12 at 15:07
1

You should look at h2 before you convert. It looks like it does not include the decimal point. Convert.ToDouble might require the leading 0 to know it's a fraction also, I am not certain.

In general this is a lot easier with a regex. See this answer.

Community
  • 1
  • 1
tallseth
  • 3,547
  • 1
  • 20
  • 24
  • Thanks, but I did that and substring is OK including the 0. Didn't want to clutter to much code into the original Q. Will check out RegEx. – EluciusFTW Aug 23 '12 at 15:09
1

Use a RegEx query like this:

^KL\d+ Traitor #\d \- \+XX\-\+(\d+\.\d+) \- .+

A grouping (expression in brackets) will give your the result.

See the sandbox.

abatishchev
  • 92,232
  • 78
  • 284
  • 421
  • Thanks, I will try regex. But it wont be quite as easy as in your code, becaus I was unclear in my Q: The word 'Traitor', the length of the string, the presence of "#2" are all flexible, but all the strings I need to read have the same structure in terms of the '-' character, which is why I opted to split the string at this charakter. – EluciusFTW Aug 23 '12 at 15:23
  • @ToaoG: Sure, I understood, my version of regex is more stric but you can make it less strict using `.+` meaning "any character or more". – abatishchev Aug 23 '12 at 15:48
0

Print h2 in the first code example to see if you are doing the substring extraction correctly.

Also using a regular expression to extract the numer would more straigthforward.

Tulains Córdova
  • 2,358
  • 2
  • 15
  • 31
  • Yes, have checked all the obvious problems, like substring etc. numerous times, didn't want to clutter the Q with too much code. – EluciusFTW Aug 23 '12 at 15:05
0

Use Regex

(?<=\+)([0-9\.])+
msmucker0527
  • 4,916
  • 2
  • 20
  • 36