There is a method that parses the string of the form ширина:долгота@ширина:долгота@...@@ and fills the two-dimensional array int[x][2] :

 void fillArr(String line, int **arr) { line += "@@"; int x = 0; int lng = line.length(); byte i = 0; char char_array[lng + 1]; strcpy(char_array, line.c_str()); String str = ""; arr[0] = new int[2]; while( x < lng - 1 ){ if(char_array[x] == ':' || char_array[x] == '@') { int num = str.toFloat() * 1000000; str = ""; if (char_array[x] == ':') { arr[i][0] = num; } else { arr[i][1] = num; i++; arr[i] = new int[2]; } x++; continue; } str += char_array[x++]; } } 

method call:

 int **arr = new int *[2]; fillArr(str, arr); 

But after several passes (5-7 pairs of values), the program pours, what can be problematic? Didn't the whole memory of the crystal get clogged up?

int num = str.toFloat() * 1000000; - it is used for trimming non-significant digits and saving only significant

With the number of pairs up to 5-7, the program works and fills the array as expected. Ie on the output you can get something like this:

 arr[0][0] - широта 1; arr[0][1] - долгота 1; arr[1][0] - широта 2; arr[1][1] - долгота 2; arr[2][0] - широта 3; arr[2][1] - долгота 3; arr[3][0] - широта 4; arr[3][1] - долгота 4; 

49.46666813651794:32.06716351318357@49.47983057360329:32.08364300537107@49.46767217581145:32.106817291259745@49.45082390409025:32.11076550292967

executing code:

 for (int i = 0; i < 4; i++) { Serial.print(arr[i][0]); Serial.print(" "); Serial.println(arr[i][1]); } 

I get:

 49466668 32067166 49479832 32083644 49467672 32106820 49450824 32110768 
  • Because you select an array with 2 pointers, and not with x pointers, i.e. you have int[2][2] instead of int[x][2] and at 3 iterations going beyond the bounds of the array when accessing arr[i] . - VTT
  • An array of type int[x][2] cannot be accessed using the int ** pointer. You do not create int[x][2] , but an "intruded" array int *[2] from pointers to arrays. And you always create an array of 2 на 2 , and not x на 2 . Why always 2 на 2 ? - AnT
  • 2
    @JVic: I don’t see where in your code x appears when allocating memory for an array. You create the top level array as new int *[2] . Subarrays are created as new int[2] . Everywhere strictly written 2. No x when creating arrays does not appear. - AnT
  • 2
    This is possible because an Undefined Behavior occurs when the array goes beyond the bounds of the array. - VTT
  • one
    Use std::vector<std::array<int, 2>> arr , pass it by reference and add new elements to it via arr.emplace_back(num, 0); . - VTT

1 answer 1

This is done differently.

 /** * Класс строки размеров. */ class WidthHeightLine : public String { public: /** * Класс указателя на позицию в строке. */ typedef int Pointer; /** * Конец строки или есть ещё размеры? */ inline bool isEndOfLine(const Pointer &ptr) const { return (*this[ptr] == '@'); } /** * Возвращает float. */ float getFloat(Pointer &ptr) const { float result = 0.0; while( *this[ptr] != '.' ) { if (isEndOfLine(ptr)) return result; result *= 10; result += *this[ptr] - '0'; ++ptr; } ++ptr; // Скипаем точку float divider = 0.1; while( *this[ptr] != ':' && ! isEndOfLine(ptr)) { result += (*this[ptr] - '0') * divider; divider /= 10; ++ptr; } return result; } /** * Возвращает длину */ inline float getWidth(Pointer &ptr) const { return getFloat(ptr); } /** * Возвращает высоту */ inline float getHeight(Pointer &ptr) const { return getFloat(ptr); } /** * Скипает разделитель (':' или '@') */ inline void skipDivider(Pointer &ptr) const { ++ptr; } /** * Класс-вектор размеров */ class WHVector { int m_size; /// Длина вектора typedef float[2] WH; /// Тип длина:высота typedef WH* PWH; /// Тип указателя PWH *m_vector; /// Вектор указателей public: /** * Конструктор */ WHVector() { m_size = 0; } /** * Освобождает вектор */ void freeVector() { for (int n = 0; n < m_size; ++n) delete m_vector[n]; if (m_size) delete m_vector; m_size = 0; } /** * Деструктор */ ~WHVector() { freeVector(); } /** * Увеличивает вектор */ WHVector& operator ++ () { PWH *newVector = new PWH[m_size+1]; for (int n = 0; n < m_size; ++n) newVector[n] = m_vector[n]; delete m_vector; newVector[m_size] = new WH; ++m_size; return *this; } /** * Возвращает ссылку на элемент вектора */ inline WH& operator [] (int n) { return *(m_vector[n]); } }; /** * Возвращает вектор переменных в заданной строке */ static int getVector( WHVector &vector, const String &line ) { WidthHeightLine &whLine = *((WidthHeightLine*) &line); vector.freeVector(); Pointer ptr = 0; int n = 0; while( ! whLine.isEndOfLine(ptr)) { vector++; vector[n][0] = whLine.getWidth(ptr); whLine.skipDivider(); vector[n][1] = whLine.getHeight(ptr); whLine.skipDivider(); ++n; } return n; } }; 

And now we call the function to get an array of sizes of type float [2]:

 WidthHeightLine::WHVector vector; int count = WidthHeightLine::getVector( vector, line ); Serial.print(count); Serial.println(" sizes found."); for (int n = 0; n < count; ++n) { Serial.print(vector[n][0], 5); Serial.print(" "); Serial.println(vector[n][1], 5); } 

Where line is a string with dimensions.

  1. We do not copy strings, but work with a pointer,
  2. We release allocated memory when it is no longer needed,
  3. We know where the end of the line is,
  4. We know how many in the size bar,
  5. The code is readable and understandable.