Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: Is "split" a valid command for a string?

  1. #1
    Member
    Join Date
    Dec 2016
    Location
    Buena Park ca
    Posts
    90

    Is "split" a valid command for a string?

    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 by laptophead; 02-02-2020 at 01:42 AM.

  2. #2
    Senior Member
    Join Date
    Feb 2015
    Location
    Finland
    Posts
    183
    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).

  3. #3
    Member
    Join Date
    Dec 2016
    Location
    Buena Park ca
    Posts
    90
    Thanks a lot, I will try

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •