Convert string to an array

Im receiving a String like this:

200,200,219,204,200,200,197

I want to convert that into an array. My first approach is to add brackets to both ends giving me a list like this:

[200,200,219,204,200,200,197]

String msg = "[";

for (int i = 6; i < len; i++)
{
  //  Serial.print((char)data[i]);
  msg += (char)data[i];
}

msg += "]";
Serial.println(msg);

But how can I convert this string into an array?

It looks to me like it's already an array.

What do you want to do?

No the type is a String. I want to convert the type into an array so I can treat it and handle it as an array

If you want to treat data that is already in an array, as an array, why convert it to a datatype that is just an array in a posh frock?

What are you trying to do?

1 Like

something like this maybe...

String msg = "[200,200,219,204,200,200,197]";

int arr[7];
int i,j,k=0;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  Serial.println("test");

  i = msg.indexOf('[');
    
  //splits string, convert 'string' values to integers and place into int array
  while(i++>-1){
    j = msg.indexOf(',',i);
    arr[k++]= msg.substring(i,j).toInt();
    i = msg.indexOf(',',j);
  }
  
  //print out int array
  for(i=0; i<k; ++i){
    Serial.println(arr[i]);
  }
}

void loop(){

}

hope that helps...

2 Likes

why do you receive integer data as strings?

Maybe it's better to start on the sending side of this data, to send and receive it as bytes?

as I said. It is not an array. It is a string :wink: Only because it looks like an array doesnt mean it actually is an array by type

It is JSON data from websocket

There are seven (comma separated) ASCII coded data items -- is it correct? If so, where have you saved them? Let me know the name of the variable and its data type.

that is one way of doing it. Im more used to javascript and python then c++ so basically was looking for a more compact way of parsing JSON data.

Another c++ related question. Do I always need to specify the length of the array as a fixed number? The length of the array received as JSON through websocket is dynamic and possible to change in size from the client side. So at this point it is 7 positions but it can vary

that's the very reason I dont particularly like those coding languages! :slight_smile:

you could set the you array as a local valuable and using the length of the received string to set its size, ie for example:

int arr[msg.length()];

a more memory efficient way however would probably be counting the number of a 'commas' in your string but I'll you try and figure that one out! :wink:

hope that helps...

The String class uses an array under the hood. You can access that array using the c_str() method.

If your approach to the problem is sensible is another question. As others said, data is an array; is it not possible to work on that? Do you need those square brackets?

You could use the textparser library:

#include <textparser.h>

void setup() {
  Serial.begin(9600);

  char const* data {"200,200,219,204,200,200,197"};

  TextParser parser {","};
  uint8_t values[7];
  parser.parseLine(data, values);

  for (uint8_t const& value: values) {
    Serial.println(value);
  }
}

void loop() {}

If data is of type String, then the following should work:

  String data {"200,200,219,204,200,200,197"};

  TextParser parser {","};
  uint8_t values[7];
  parser.parseLine(data.c_str(), values);

Thanks. This is working.

    String msg = "";

    for (int i = 0; i < len; i++)
    {
      msg += (char)data[i];
    }

    TextParser parser{","};
    uint8_t values[7];
    parser.parseLine(msg.c_str(), values);

However when trying to set a more dynamic length of the array by counting the commas like below the application wont compile when using the value from count to set the length of the array:

    String msg = "";

    for (int i = 0; i < len; i++)
    {
      msg += (char)data[i];
    }

    // count commas to get the length of array
    int count = 0;
    for (uint8_t i = 0; i < len; i++)
    {
      if (msg[i] == ',')
        count++;
    }
    // adding the last element
    count = count + 1;

    Serial.println(count);

    TextParser parser{","};
    uint8_t values[count];
    parser.parseLine(msg.c_str(), values);

This is not allowed in C++. The expression between the brackets needs to be constant.

Ah ok. Is there a workaround to get a dynamic length of the array that you can update according to a variable?

No, the size of an array needs to be known at compile time. You could have a look at std::vector instead, but it is not available on all platforms and the textparser library does not support it.

For this use case, I would simply set the array size to the maximum number of data points.

By the way,

why not simply pass data to parseLine?

Had the same problem a while back. Putting the code here in case you are interested having dynamically sized array using std::vector. Obviously works only on platforms which have 'string' and 'vector' available, which should be most ARM-based platforms.

#include <string>
#include <vector>

std::vector<int32_t> string_to_vector(
                std::string& str, std::string delimiter = ",") {
    
    std::vector<int32_t> res;
    auto pos = str.find(delimiter);
    
    while (pos != std::string::npos) {
        res.emplace_back(strtol(str.substr(0, pos).c_str(), NULL, 10));
        str.erase(0, pos+1);
        pos = str.find(delimiter);
    }
    // Handle the last element if it is not followed by the delimiter.
    res.emplace_back(strtol(str.substr(0, pos).c_str(), NULL, 10));
    
    return res;
}

void setup(void) {
    Serial.begin(57600);
    while (!Serial) {} // Wait for serial.
    
    /* Works as intented. */
    std::string test_input = "123, 345, 678, 666, 777, 888, 321, 432";
    auto results = string_to_vector(test_input); 

    /* Works as intented. */
    //std::string test_input = "221; 5; 7; 12; -8; -123; 550";
    //auto results = string_to_vector(test_input, ";"); 
    
    /* Returns extra '0' at the end. */
    //std::string test_input = "5, -2, -1, 25,";
    //auto results = string_to_vector(test_input);
    
    /* Elements starting with text return '0'. */
    //std::string test_input = "aaa, 15qwerty, bb22, -5";
    //auto results = string_to_vector(test_input);
    
    std::string s = "Found " + std::to_string(results.size()) + " values";
    Serial.println(s.c_str());
    for (auto it = results.begin(); it != results.end(); ++it) {
        Serial.println(*it);
    }
}

void loop(void) {
    
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.