user1054922
user1054922

Reputation: 2165

atof() in Java? No exception throwing

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

Answers (5)

Shivan Dragon
Shivan Dragon

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

WillBD
WillBD

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

Charles Forsythe
Charles Forsythe

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

Axel
Axel

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

givanse
givanse

Reputation: 14943

One option is to use StringTokenizer, using . as the separator, and then use only the first two tokens for conversion.

Upvotes: 2

Related Questions