Reputation: 2165
I want to parse a string in the format '5.3984.234' and convert it to a float. Obviously the float will be 5.3984
In C, using atof() will give this result, but in Java, Float.parseFloat() and Float.valueOf() both throw exception.
I do not want the function throwing an exception and want the identical functionality of atof() How can I do this?
Note: I can't guarantee there is always two periods in the string. Sometimes it might be 48328.458, other times 4823.5482.4822 or even 42894.4383.8349.439
Upvotes: 0
Views: 578
Reputation: 15219
In Java you can do this:
//this only works if the string has exactly two points (two '.' characters)
//(sorry, I misread the question)
//String string = "1.2341.234";
//float f = Float.parseFloat(string.substring(0, string.lastIndexOf(".")));
//for any number of points in the string:
String string = "1.2.3";
String[] elems = string.split("\\.");
float f = Float.parseFloat(elems.length==1 ? string : elems[0]+"."+elems[1]);
Upvotes: 0
Reputation: 1919
Well, first and foremost atof() can return undefined behaviour, so I wouldn't want to emulate that exactly ;) see:
atof() with non-nullterminated string
for what I mean by that.
Anyway, to solve you problem using Java, I would approach it with a String.substring method, where you simply parse the string up until the second '.', and then do whatever of the functions you'd like with it. Albeit, if you don't care about throwing away everything after the second '.' it gets a lot easier.
And here's some code to make what I mentioned work:
public class main{
public static void main(String[] args)
{
String test = "5.3984";
int tempIndex = 0;
tempIndex = test.indexOf('.');
tempIndex = test.indexOf('.', tempIndex + 1 );
if (tempIndex != -1)
{
System.out.println("multiple periods: " + Float.parseFloat(test.substring(0, tempIndex)));
}
else
{
System.out.println("Only one Period: :" + Float.parseFloat(test));
}
}
Now, this may not be super robust, but it seems to work ok.
Upvotes: 2
Reputation: 1861
You need to separate the proper leading floating point representation from the additional data following it. This is what I would do:
Pattern p = Pattern.compile("^(-?\\d+(\\.\\d+)?)");
Matcher m = p.matcher(stringWithFloatInIt);
if (m.find()) {
f = Float.parseFloat(m.group(0));
} else {
// String was not even CLOSE to a number
}
Upvotes: 0
Reputation: 14159
Double.parseDouble()
always processes the whole String. Since you have to decimal points in it, it will throw a NumberFormatException. I am also not convinced yours is the obvious result. The input is either malformed or locale dependent (you could also expect a value of 53984234).
Upvotes: 1
Reputation: 14943
One option is to use StringTokenizer, using .
as the separator, and then use only the first two tokens for conversion.
Upvotes: 2