#26 2025-08-05 13:56:58

filat18
Учасник
Зареєстрований: 2025-08-04
Повідомлень: 20

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

Загальні вимоги до  скетчу:
1 Якщо приходить повідомлення в вигляді цислового масива не визначеної довжини (від 1 до до 5, наприклад: 1/24/35 або 759/ або1/0/245/657/841 або...) треба занесті відповідні числа у масив rArr. Ділянки масиву, що не отримали новид даних, повинні отримати 0.
2. після отриманя числовиго массина та розкладання його у rArr, потрібно викликати зовнішний void.
3. ящо у повідомленні є символи, що не належать числовому масиву, всі значення rArr потрібно перетворити у 0  і перейти до очикування наступного сповіщення.

Остання редакція filat18 (2025-08-05 13:58:48)

Неактивний

#27 2025-08-05 14:22:55

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 155

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

Ви намагаєтесь робити складно. Робіть просто.
1. просто приймайте символи в буфер. Коли приймете n - обробіть весь буфер зразу. Якщо буфер переповниться - ну, придумайте щось. Це помилка в даних.
2. обробка буфера. знаходите розділювачі полів, викусюєте частини з цифрами, перетворюєте в int. int кидаєте в масив.
Весь алгоритм.
Не треба придумувати байто@0bства на рівному місці. Не треба економити рядки коду. Не треба придумувати саморобні парсери. atoi нормально працює.

Неактивний

#28 2025-08-05 15:12:32

filat18
Учасник
Зареєстрований: 2025-08-04
Повідомлень: 20

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

Мав меркування, що розділення на масив має буте швидше, ниж займатися розділом після отримання...
Но ті результати, що отримую та Ваші зауваження - підтвержують хибність моїх меркувань...

Неактивний

#29 2025-08-05 15:17:58

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 570

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

filat18 пише:

!? як що закоментувати позначений рядок - маю наступну відповідь, при однаковому сповіщєнні

Тому що rIndex=0 у вас не там де він повинен бути.

filat18 пише:

Але чи не простіше було б просто надрукувати уривок коду, що дійсно працює?

Та мабуть, простіше. Тільки розуміння того, що таке "дійсно працює", у нас з вами, мабуть, дуже різне.
Ось вам приклад. Написав якомога простіше, по-ардуінівськи. Ніякої обробки помилок у вхідних даних нема: що не влазить, те ігнорується, що atoi() повертає, те і записується. Обробка помилок на вході - то вже на ваc.

void setup()
{
    Serial.begin(115200);
}

size_t idx { 0 };
size_t str_idx { 0 } ;

int data[10];
char str[7];

void push_number()
{
    if (idx < sizeof(data)/sizeof(*data)) {
        str[str_idx] = '\0';
        data[idx++] = atoi(str);
    }
}

void loop()
{
    for (int c; (c = Serial.read()) != -1;)
    {
        switch (c) {
            case '/':
                push_number();
                str_idx = 0;
                break;

            case '\n':
            case '\r':
                if (idx == 0 && str_idx == 0) {
                    break;
                }
                push_number();

                for (size_t i = 0; i < idx; i++) {
                    Serial.print(F("data["));
                    Serial.print(i);
                    Serial.print(F("] = "));
                    Serial.println(data[i]);
                }

                idx = 0;
                str_idx = 0;
                break;

            default:
                if (str_idx < sizeof(str)/sizeof(*str) - 1) {
                    str[str_idx++] = c;
                }
                break;
        }
    }
}

Неактивний

#30 2025-08-05 15:26:15

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 155

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

розділення на масив має буте швидше, ниж займатися розділом після отримання...

Число операцій приблизно однакове. Розпихувати операції з розбором окремих полів має смисл, якщо одна велика операція в ваші обмеження не влізе. Ну, зробите це окремою функцією, будете викликати після кожного розділювача. Головне - не робити суперфункцій з суперциклами і глобальними суперзмінними. Робіть функції прості і зрозумілі.

Неактивний

#31 2025-08-05 15:35:57

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 570

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

UPD: запостив приклад до того як побачив ваші наступні повідомлення з описом задачі.

filat18 пише:

Ділянки масиву, що не отримали новид даних, повинні отримати 0.

Так обнуліть їх перед тим як передавати кудись той масив.

Якщо так вже кортить обнуляти весь масив перед отриманням нового рядка, то

memset(rArr, 0, sizeof(rArr));

Або, те ж саме:

for (auto &it : rArr) {
    it = 0;
}

Або, те ж саме:

for (auto *p = rArr; p < rArr + sizeof(rArr)/sizeof(*rArr);) {
    *p++ = 0;
}

Або, те ж саме:

for (size_t i = 0; i < sizeof(rArr)/sizeof(*rArr); i++) {
    rArr[i] = 0;
}

Можна навигадувати ще багато способів обнулити масив в C++.

Неактивний

#32 2025-08-05 15:41:38

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 155

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

sizeof(data)/sizeof(*data)

Не люблю. І щось мені здається що там помилка wink

#define DATA_SIZE 10
int data[DATA_SIZE];

Просто і зрозуміло.

Неактивний

#33 2025-08-05 15:59:33

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 570

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

filat18 пише:

1 Якщо приходить повідомлення в вигляді цислового масива не визначеної довжини (від 1 до до 5, наприклад: 1/24/35 або 759/ або1/0/245/657/841 або...) треба занесті відповідні числа у масив rArr.

А якщо приходить більше ніж 5 чисел, решта має ігноруватись?
Чи потрібно передати 5 уже отриманих чисел, а решту розглядати як наступний рядок?
Чи весь такий рядок має ігноруватись до наступного?

filat18 пише:

2. після отриманя числовиго массина та розкладання його у rArr, потрібно викликати зовнішний void.

Спробую вгадати, що "викликати зовнішний void" - це передати масив у іншу функцію?

filat18 пише:

3. ящо у повідомленні є символи, що не належать числовому масиву, всі значення rArr потрібно перетворити у 0  і перейти до очикування наступного сповіщення.

Тобто ігнорувати цей рядок.
А якщо число 32768 чи більше, яке не влазить в AVR'івський int? Яке максимально допустиме значення, і що програма має робити зі значеннями, які його перевищують?

Неактивний

#34 2025-08-05 16:07:24

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 570

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

jokeR пише:
sizeof(data)/sizeof(*data)

Не люблю.

Не смію вам перешкоджати щось не любити, маєте на це повне право wink

jokeR пише:

І щось мені здається що там помилка wink

Аргументуйте, в чому саме помилка.

jokeR пише:
#define DATA_SIZE 10
int data[DATA_SIZE];

Просто і зрозуміло.

Просто і зрозуміло - це std::array та std::vector. А в ардуіно - що маємо, те маємо.

Неактивний

#35 2025-08-05 16:19:33

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 155

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

sizeof(data)/sizeof(data[0]) часто зустрічаю. Теж не люблю.  А так.. Неочевидно трохи. Я здогадуюсь що в С масив і вказівник майже синоніми, і так теж можна. Але в такому записі легко допустити помилку, і компілятор її нормально пропустить. І фіг потім знайдете що не так wink

Неактивний

#36 2025-08-05 16:31:00

filat18
Учасник
Зареєстрований: 2025-08-04
Повідомлень: 20

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

dimich, дякую за варіант коду - дуже цікаво! З затиранням даних зрозуміло. А от що цікаво: код дає різну кількість отриманих груп для повідомлення 4/5 і для 4/5/

Неактивний

#37 2025-08-05 16:38:30

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 570

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

jokeR пише:

Але в такому записі легко допустити помилку, і компілятор її нормально пропустить.

Компілятор взагалі багато чого нормально пропускає. Для того і потрібна прокладка між стільцем та клавіатурою.

#define ARRAY_SIZE(x)  (sizeof(x)/sizeof(*(x)))

Або взагалі std::array без кофеіну:

template <typename T, size_t N>
struct array
{
    T data[N];
    constexpr size_t size() const noexcept { return N; }
};

А там можна і оператор [] перевантажити, і ітератори прикрутити.

Неактивний

#38 2025-08-05 16:44:21

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 570

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

filat18 пише:

А от що цікаво: код дає різну кількість отриманих груп для повідомлення 4/5 і для 4/5/

Так, тому що між розділювачем / та кінцем рядка пусто. atoi() для пустого рядка повертає 0.

Неактивний

#39 2025-08-05 17:18:39

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 155

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

Бо не домовились що робити з пустими полями.
Взагалі без розуміння задумки автора - складно.

Неактивний

#40 2025-08-05 17:58:29

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 570

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

jokeR пише:

sizeof(data)/sizeof(data[0]) часто зустрічаю.

data[0] - це те ж саме, що *(data + 0), тобто *(data), тобто *data

Неактивний

#41 Сьогодні 12:23:38

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 570

Re: Чому повідомлення не вдається розкласти в масив без затримки часу

dimich пише:

Просто і зрозуміло - це std::array та std::vector. А в ардуіно - що маємо, те маємо.

Доречі, Determining the Number of Elements of Arrays.

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму