TheLostJedi Ответов: 1

Удаление лишних байтов из данных последовательного порта


Привет ребята,
Итак, я реализую блестящий серийный класс, созданный Реймон де Клейн здесь:
Последовательная библиотека для C++[^]

В своем определении функции чтения он записывает входящие байты в массив размером 100. Проблема в том, что когда я отправляю пакет данных, размер которого, как я знаю, меньше 100, он поставляется в комплекте с мусором в качестве оставшихся байтов.

Я хочу отфильтровать это.



Есть какие-нибудь предложения относительно того, что я мог бы попробовать дальше?

Что я уже пробовал:

1. Магазин поступающих данных в CString, а функция определяет переменную буфера как Void* буфер. Поэтому преобразование не работает.
2. динамически объявляйте переменную буфера на основе количества полученных байтов, но функция не принимает массив неопределенного размера.

Richard MacCutchan

Нет, он не поставляется с дополнительными данными, у вас просто есть мусор в вашем буфере. Вам нужно проверить размер каждого входящего сообщения, чтобы убедиться, что вы обрабатываете только фактическое количество полученных байтов.

TheLostJedi

Но как бы я это сделал, если бы мне пришлось объявить размер буфера до того, как порт будет прочитан?
Поможет ли опустошение буфера?

Richard MacCutchan

Вы проверяете на каждом чтении, сколько байтов было возвращено. Последовательные устройства возвращают данные в случайном количестве, и вы никогда не можете быть уверены, сколько их будет, поэтому вам нужно управлять ими соответствующим образом.

1 Ответов

Рейтинг:
12

Jochen Arndt

Просто не используйте дополнительные байты. Обычно вы знаете, сколько байтов было получено.

Выделите а char* буфер, достаточно большой для хранения максимальной длины данных (опционально плюс один байт для нулевого Терминатора).

Если вы знаете, что данные являются печатаемыми символами, и хотите создать строку, вы должны указать длину или добавить нулевой байт в буфер.

Чтобы скопировать данные в CString Вы можете использовать

/* Use the constructor for char* because data are usually ASCII. */
/* Note that this converts to Unicode for Unicode builds. */
CString str(buffer, dwRead);

/* Using a CStringA and setString(): */
CStringA strA;
strA.SetString(buffer, dwRead);
Или добавьте нулевой байт в буфер:
/* Check for buffer overrun. */
/* RX_BUF_SIZE is the size of the allocated buffer. */
ASSERT(dwRead < RX_BUF_SIZE);
buffer[dwRead] = 0;

CString str(buffer);


TheLostJedi

Означает ли это, что будут сохранены только байты перед нулевым байтом?
Мне очень жаль, но я не думаю, что понял некоторые части. Вы добавляете нуль после количества прочитанных байтов. Итак, если я инициализировал буфер с большим размером, означает ли это, что преобразование в печатную форму остановится на нуле?

Jochen Arndt

Базовая строка C/C++ должна иметь завершающий нулевой символ. Это конечный показатель. При получении данных этого конечного индикатора нет. Так что у вас есть два варианта:
- Добавьте его за полученными данными (буфер должен быть достаточно большим)
- Копирование данных в какую-либо строку с использованием известной длины

Строковые функции стандартной библиотеки C (например, strcpy, strcmp) требуют, чтобы строки заканчивались null.

Другие классы, такие как CString, отслеживают длину внутри себя. Но при передаче классических строк (char*) они должны быть завершены нулем или должна быть указана длина.