Двухмерный массив?
- Войдите на сайт для отправки комментариев
Пт, 15/04/2016 - 22:18
Привет.
Суть: я скажем храню номера телефонов в EPPROM ардуины.
Скажем каджый байт - 1 знак из номера телефона (12 знаков - 1 номер).
Сколько всего номеров - не известно, но останавливаюсь читать EPPROM когда следущий байт = 255.
У меня проблема с выводом массива:
Код с ошибкой:
/* Читаем телефоны с EPPROM */
String[] getPhoneNumbers() {
String numbers[];
/*
Чтение телефонов начинается с 49го адресса
Один телефон занимает + 38 44 34 44 44 44 == 12 байт
*/
int numI = 0;
for (int addr = 49; addr < 1024; addr++) {
int n = EEPROM[addr];
// Конец списка телефонов
if(n == 255) {
break;
}
if(sizeof(numbers[numI]) == 12) {
numI++;
}
numbers[numI] += n;
}
return numbers;
}
И в переделке на char* он тоже не заносит.
Суть массива такая:
numbers[0] = "381038274937";
numbers[1] = "911638374237";
т.е. обьявить изначально кол-во элементов я не могу, так как не знаю сколько их. Как-то можно решить эту задачу?
Можно. Написав нормальный код. Вы на голом С++ это хотите сделать? Это не так тривиально, как может показаться на первый взгляд, тем более - вы не знаете заранее, сколько так номеров телефонов. Вкратце - надо курить malloc/realloc/free - такие старые добротные хорошие сишные функции (new/delete, собственно, внутри себя их и юзают). Не зная заранее кол-ва элементов в массиве - только с ними и работать.
Навскидку без ошибок не напишу (даже вернее всего - будут ошибки), но как-то так:
/* Читаем телефоны с EPPROM */ char** getPhoneNumbers(int& array_size) { byte buff[13] = {0}; char** result = NULL; array_size = 0; /* Чтение телефонов начинается с 49го адресса Один телефон занимает + 38 44 34 44 44 44 == 12 байт */ int readed = 0; for (int addr = 49; addr < 1024; addr++,readed++) { byte n = EEPROM[addr]; if(n == 255) break; if(readed < 12) buff[readed] = n; else { buff[readed] = 0; readed = 0; // в buff лежит номер телефона, надо скопировать его в массив if(!array_size) { result = new char*[array_size+1]; result[array_size] = new char[sizeof(buff)]; strcpy(result[array_size],buff); array_size++; } else { char **copy = new char* [array_size+1]; for(int j = 0;j < array_size; j++) { copy[j] = result [j]; } delete [] result; result = copy; result[array_size] = new char[sizeof(buff)]; strcpy(result[array_size],buff); array_size++; } } } return result; }Собственно, принцип понятен, надеюсь. Только не забывайте освобождать память после использования. А ещё лучше - перейти на другой уровень абстракции - классы. Чтобы не париться с памятью, как в приведённом примере, а отдать это на откуп конкретной реализации класса.
Кстати, а чего Вы ждёте от выражения
sizeof(numbers[numI])в строке 21? Текущей длины строки numbers[numI]? Таки нет - Вы получите размер объетка String в памяти - это фиксированная величина. Если нужна длина, то см. методы класса String.Можно. Написав нормальный код. Вы на голом С++ это хотите сделать? Это не так тривиально, как может показаться на первый взгляд, тем более - вы не знаете заранее, сколько так номеров телефонов. Вкратце - надо курить malloc/realloc/free - такие старые добротные хорошие сишные функции (new/delete, собственно, внутри себя их и юзают). Не зная заранее кол-ва элементов в массиве - только с ними и работать.
Навскидку без ошибок не напишу (даже вернее всего - будут ошибки), но как-то так:
/* Читаем телефоны с EPPROM */ char** getPhoneNumbers(int& array_size) { byte buff[13] = {0}; char** result = NULL; array_size = 0; /* Чтение телефонов начинается с 49го адресса Один телефон занимает + 38 44 34 44 44 44 == 12 байт */ int readed = 0; for (int addr = 49; addr < 1024; addr++,readed++) { byte n = EEPROM[addr]; if(n == 255) break; if(readed < 12) buff[readed] = n; else { buff[readed] = 0; readed = 0; // в buff лежит номер телефона, надо скопировать его в массив if(!array_size) { result = new char*[array_size+1]; result[array_size] = new char[sizeof(buff)]; strcpy(result[array_size],buff); array_size++; } else { char **copy = new char* [array_size+1]; for(int j = 0;j < array_size; j++) { copy[j] = result [j]; } delete [] result; result = copy; result[array_size] = new char[sizeof(buff)]; strcpy(result[array_size],buff); array_size++; } } } return result; }Собственно, принцип понятен, надеюсь. Только не забывайте освобождать память после использования. А ещё лучше - перейти на другой уровень абстракции - классы. Чтобы не париться с памятью, как в приведённом примере, а отдать это на откуп конкретной реализации класса.
Нет, делаю в Arduino Studio.
Спасибо за пример, буду разбирать
Я не совсем понял как сделать двухмерный массив. А sizeof думал выдаст мне не общее кол-во массива, а кол-во ключей :)
Про String я знаю :)
Я не совсем понял как сделать двухмерный массив. А sizeof думал выдаст мне не общее кол-во массива, а кол-во ключей :)
sizeof выдаёт размер объекта в памяти в момент компиляции и ничего больше
Про String я знаю :)
Не знаете. Изучайте.
в условиях очень ограниченной "кучи" в МК не следует злоупотреблять malloc().
То есть не стоит часто отводить и высвобождать память не думая о последовательности дейстий.
В Вашем случае нужно один раз пробежать по EEPROM и узнать количество телефонов, а потом отвести под них память и вторым проходом туда прочитать. То есть отвести память один раз, потом, воспользовавшись телефонами, освободить память тоже один раз.
И еще вопрос: цифра номера это 4 бита, в байт одним макросом пакуется 2- цифры и столь же простым макросом - извлекаются.
Правда это имеет смысл только в том случае, если в проекте есть нехватка памяти, если на все хватает, то и не стоит огород городить.
Вот макросы для паковки и распаковки. М - массив unsigned char, i - индекс, a - цифра.
Вот макросы для паковки и распаковки. М - массив unsigned char, i - индекс, a - цифра.
Негодные макросы, небезопасные. Предлагаю подумать, как распакуется макрос, если я его вызову так:
;)
конечно нужно еще скобок поставить вокруг переменных, это же на коленке написано... ;) ну что Вы прямо!?