Is "split" a valid command for a string?

Status
Not open for further replies.

laptophead

Well-known member
I does show in red in the IDE , so it does exists, but I get a
'class String' has no member named 'split'

Long story short, I am trying to extract values (Floats) from a string based on the space between them

FromTablet = Serial5.readStringUntil('\n'); gets me:

g 117.1 230.0 112.9 180.0 54.8 77.7 112.9 0.0 Is my incoming string ended in a newline

Then I tried
String AngStr[20] = FromTablet.split(" "); ( found it on some forums...)

hoping to get a bunch of baby strings containing my values,

Then I would convert those to Floats such as:

AngStr_float[1] = AngStr[1].toFloat();
etc

Any ideas of the most efficient way to do this?
Thanks
Mitch
 
Last edited:
Better write your own float parser. Let's see:
Code:
int parseFloats(char *buffer, float to[], int max)
{
    int count = 0;
    float value;
    float divisor;

    while (*buffer) {
        if (*buffer == ' ' || *buffer == '\t') {
            buffer++;
            continue;
        }

        value = 0.0f;
        divisor = 1.0f;
        while (*buffer == '+' || *buffer == '-') {
            if (*buffer == '-') {
                divisor = -divisor;
            }
        }

        // Digit or decimal point required.
        if (*buffer != '.' && !(*buffer >= '0' && *buffer <= '9')) {
            break;
        }

        // Integer part
        while (*buffer >= '0' && *buffer <= '9') {
            value = (10.0f * value) + (float)(*(buffer++) - '0');
        }

        // Decimal point?
        if (*buffer == '.') {
            buffer++;

            while (*buffer >= '0' && *buffer <= '9') {
                if (value < 1000000000000.0f) {
                    value = (10.0f * value) + (float)(*(buffer++) - '0');
                    divisor = divisor * 10.0f;
                } else {
                    // Float type doesn't have that many significant digits, so ignore the trailing ones.
                    buffer++;
                }
            }
        }

        if (count < max) {
            data[count] = value / divisor;
        }
        count++;
    }

    return count;    
}
This is similar to the Stream.parseFloat() in various Arduino core libraries, but instead of multiplication, uses division. (Multiplication by 0.1 is not precise, but the core libraries use it because it is faster than division. You can fix that by using a fixed array of floats of negative powers of ten, if efficiency is that important -- it's not like one division per float is that slow.)

If you have char fromTablet[] = "g 117.1 230.0 112.9 180.0 54.8 77.7 112.9 0.0\n"; float angles[9]; then calling parseFloats(fromTablet + 1, angles, 9) should return 9 (for nine floats parsed) with the angles[] array filled in. The +1 skips the initial letter.

Note that this does not require spaces between numbers. It would happily parse "117.1+230.0+112.9+180.0+54.8+77.7+112.9+0.0\n" or say "1-2.0+4.5 2.0-0.1+4 57.8889-2.5+.4" (to 1.0f, -2.0f, +4.5f, 2.0f, -0.1f, 4.0f, 57.8889f, -2.5f, and 0.4f).
 
Status
Not open for further replies.
Back
Top