|
Вопрос # 5 644/ вопрос открыт / |
|
Здравствуйте, уважаемые эксперты! Помогите решить задачу. В поле мемо приходят данные из ком порта. Помимо нужных данных, приходит различный хлам, который не нужен. Нужные данные отметил символом, чтобы различать, примерно так:
x-23
y34
r345
p-34
y1
нужно сделать проверку, если в первой строке есть "x" то в переменную(например xd) нужно записать число после "x"... если во второй строке есть "у" то записываем в переменную уd число после "у" и т.д.
Как бы это рационально сделать т.к. скорость выявления хлама от полезных данных нужна большая.
 |
Вопрос задал: EvgenDRV (статус: Посетитель)
Вопрос отправлен: 19 сентября 2011, 21:17
Состояние вопроса: открыт, ответов: 1.
|
Ответ #1. Отвечает эксперт: min@y™
Я приехал с югов, мозги требуют нагрузки.
Навскидку могу предложить вот такую функцию:
type
TSplittedData = record
Symbol: Char; // первый символ строки (х, у и т.д.)
Data: Integer; // число, следующее за первым символом
Success: Boolean; // результат преобразования (true в случае успеха)
end;
// функция разделения принятой строки на составляющие
function SplitData(const S: string): TSplittedData;
begin
with Result do
begin
Success:= S <> '';
if not Success // выход с ошибкой, если строка пустая
then Exit;
Symbol:= S[1]; // первый символ
// числовые данные
Success:= TryStrToInt(Copy(S, 2, Length(S) - 1), Data);
end; // with
end;
Это не значит, что надо сразу копипастить этот код к себе в программу. Для начала проанализируй её работу. Алгоритм я представляю примерно такой:
- принять очередную строку в порт;
- скормить её функции для отделения мух от котлет;
- использовать полученные от функции данные, если Success = True.
З.Ы. Код не отлаживал, писал в браузере.
 |
Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 20 сентября 2011, 13:19
Оценка за ответ: 5
Комментарий к оценке: конечно, держи +5:)
|
Мини-форум вопроса
Всего сообщений: 8; последнее сообщение — 25 сентября 2011, 10:14; участников в обсуждении: 3.
|
Вадим К (статус: Академик), 20 сентября 2011, 10:37 [#1]:
Во первых, большая скорость Вам не нужна, навряд ли у Вас СОМ порт работает на скоростях больше 115200. Для этого хватит любого современного компьютера.
Но можно так написать, что не хватит и Вы сделали первый шаг к этому - записываете данные в мемо, модифицируете и потом пытаетесь анализировать. А нужно читать сразу на лету. Если напишете чуточку больше о том, какие данные приходят, то вполне могу помочь написать парсер-автомат, который будет парсить входной поток и распихивать параметры.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
min@y™ (статус: Доктор наук), 20 сентября 2011, 13:23 [#2]:
Можно ещё код подсократить:
type
TSplittedData = record
Symbol: Char; // первый символ строки (х, у и т.д.)
Data: Integer; // число, следующее за первым символом
Success: Boolean; // результат преобразования (true в случае успеха)
end;
// функция разделения принятой строки на составляющие
function SplitData(const S: string): TSplittedData;
begin
with Result do
begin
Success:= (S <> '') and TryStrToInt(Copy(S, 2, Length(S) - 1), Data); // числовые данные
if Success then Symbol:= S[1]; // первый символ
end; // with
end;
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
EvgenDRV (статус: Посетитель), 20 сентября 2011, 15:14 [#3]:
По правде сказать мне тоже не очень нравится, что через мемо всё идет... я тут накидал немного как примерно алгоритм должен идти, вроде работает, но смущает рационально ли так делать.
sx:= Memo1.Lines[0];
if pos('x', Memo1.Lines[0]) = 1 then
begin
delete(sx, 1, 1) ;
Label1.Caption:=sx ;
end
else
Label1.Caption:=Label1.Caption;
А с парсером на лету было бы здорово. Данные получаю от платы arduino с подключенными акселерометрами и гироскопами т.е. если нужно, данные могу получить в любом виде(в одну строку, с переносом, с разделителями и т.д). Общаюсь с платой через компонент ComPort. Получаю данные вот так:
ComPort1.ReadStr(Str, Count);
Memo1.Text := Str;
|
|
min@y™ (статус: Доктор наук), 20 сентября 2011, 15:24 [#4]:
Цитата (EvgenDRV):
А с парсером на лету было бы здорово.
Ну и чо тебе мешает использовать мою функцию?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
EvgenDRV (статус: Посетитель), 20 сентября 2011, 15:46 [#5]:
min@y™: просто что-то разобраться ещё не могу, где проверяется, что x это x? а y это у. В первой строке может быть и x и y и z... и всё что угодно, но нам нужен x...
Пытался сообразить в Вашей функции, что-то туго у меня получается.
|
|
min@y™ (статус: Доктор наук), 20 сентября 2011, 16:11 [#6]:
Цитата (EvgenDRV):
где проверяется, что x это x? а y это у. В первой строке может быть и x и y и z... и всё что угодно, но нам нужен x...
А нигде не проверяется. Функция возвращает (!) первый символ строки вместе с числом в структуре-результате. Юзать всё это можно, например, так:
var
DS: TSplittedData;
begin
// <--- тут принимаешь строку с порта в переменную S
// далее - скармливаешь её функции для извлечения данных:
DS:= SplitData(S);
if DS.Success
then begin
Label1.Caption:= S; // выводишь в Label
// далее в зависимости от первой буквы делаешь то, что тебе надо:
case DS.Symbol of
'x': xd:= DS.Data; //........ принят икс
'y': yd:= DS.Data; //........ принят игрек
'й': zd:= DS.Data; //........ принят зэт :)
// и так далее
else
sndPlaySound('mazafaka.wav', SND_ASYNC); // действие по умолчанию
end;
end;
end;
Думай. Это только пример.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
EvgenDRV (статус: Посетитель), 25 сентября 2011, 02:54 [#7]:
спасибо, разобрался, всё отлично работает!
|
|
min@y™ (статус: Доктор наук), 25 сентября 2011, 10:14 [#8]:
Цитата (EvgenDRV):
спасибо, разобрался, всё отлично работает!
Тогда где мои честные +5 баллов?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|