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(){
}
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
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?
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);
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.
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) {
}