HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavaMinor

Parse floats from a string

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
fromfloatsstringparse

Problem

While fixing some old code I came up with a class that parses floats from a string.

This is used for parsing svg files in xml format. Floats can be separated by comma, space or anything at all in case the next number starts with a sign. They can also use exponential notation.

Sample:



This is the class:

```
private class ParserData
{
String s;
int cur = 0;
int len = 0;

float prev_x = .0f;
float prev_y = .0f;

float prev_cx = .0f;
float prev_cy = .0f;

float start_x = .0f;
float start_y = .0f;

char prev_curve;
char next_curve = 0;

public void setData(String data)
{
s = data;
len = s.length();

cur = 0;
prev_x = 0;
prev_y = 0;

prev_cx = .0f;
prev_cy = .0f;

start_x = .0f;
start_y = .0f;

prev_curve = 0;
next_curve = 0;
}

public boolean hasNext()
{
return cur < len;
}

public char getNext()
{
return s.charAt(cur++);
}

public char peekNext()
{
return s.charAt(cur);
}

public void skipSpaces()
{
while(hasNext())
{
char c = s.charAt(cur);

switch(c)
{
case ' ':
case ',':
case '\n':
case '\t':
case '\r':
break;

default:
return;
}

cur++;
}
}

private float parseFloat()
{
boolean exp = false;
boolean last = false;

skipSpaces();

int j = cur;

if(s.charAt(j) == '-')
{
getNext();
}

while(hasNext() && !last)
{
char c = getNext();

switch(c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':

Solution

At least for now, I did not look at improving performance or at the general approach, but at some more basic things I think would improve the readability of the code.

setData vs Constructor

It seems to me that setData takes the role of a constructor here. In that case, I would just make it a constructor instead of making it a method. Sure, this would result in the creation of a new object, but it would result in cleaner code (the ParserData would always be a valid object).

Naming

First of all, in Java CamelCase is used instead of underscores. It's always good to follow the conventions of a language, so prev_curve for example should be prevCurve.

Variables should always have expressive names, but this is especially important at class level. Your names wouldn't tell me the difference between prev_x and prev_cx for example. s is also not a very expressive name (I cannot think of a name that's a lot better, but even string or inputString would be better. For consistency, data should then be changed to the same name).

len could be length, cur currentPosition, and c could be currentChar.

exp should probably be exponent and j also should get a more expressive name (something like startFloatString).

access modifiers

Your fields should be private.

Your skipSpaces should probably be private as well.

The parseFloat method is private, and not called from within the class. But it is the main parse method. This seems wrong, I would make it public.

Unused Fields

Defining fields and then not using them is not good practice. You should remove next_curve, prev_curve, start_y, start_x, prev_cy, prev_cx, prev_y and prev_x. I see that you do use these fields in a different context, but not in your parsing code. So I would create a new class for them instead of tagging them onto this one.

You should also remove last and change


while(hasNext() && !last)

to

while(hasNext())


Use methods that you have defined

You have getNext, so why not use it in skipSpaces instead of getting the character yourself and then increasing cur.

Same with peekNext in parseFloat.

Formating

In Java, it is customary to put the { on the same line, not the next.

Code Snippets

while(hasNext())

Context

StackExchange Code Review Q#64910, answer score: 5

Revisions (0)

No revisions yet.