Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 5 644

/ вопрос открыт /

Здравствуйте, уважаемые эксперты! Помогите решить задачу. В поле мемо приходят данные из ком порта. Помимо нужных данных, приходит различный хлам, который не нужен. Нужные данные отметил символом, чтобы различать, примерно так:
x-23
y34
r345
p-34
y1

нужно сделать проверку, если в первой строке есть "x" то в переменную(например xd) нужно записать число после "x"... если во второй строке есть "у" то записываем в переменную уd число после "у" и т.д.
Как бы это рационально сделать т.к. скорость выявления хлама от полезных данных нужна большая.

EvgenDRV Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: 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;

Это не значит, что надо сразу копипастить этот код к себе в программу. Для начала проанализируй её работу. Алгоритм я представляю примерно такой:

  1. принять очередную строку в порт;
  2. скормить её функции для отделения мух от котлет;
  3. использовать полученные от функции данные, если Success = True.


З.Ы. Код не отлаживал, писал в браузере.

Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 20 сентября 2011, 13:19
Оценка за ответ: 5

Комментарий к оценке: конечно, держи +5:)

Мини-форум вопроса

Всего сообщений: 8; последнее сообщение — 25 сентября 2011, 10:14; участников в обсуждении: 3.
Вадим К

Вадим К (статус: Академик), 20 сентября 2011, 10:37 [#1]:

Во первых, большая скорость Вам не нужна, навряд ли у Вас СОМ порт работает на скоростях больше 115200. Для этого хватит любого современного компьютера.
Но можно так написать, что не хватит и Вы сделали первый шаг к этому - записываете данные в мемо, модифицируете и потом пытаетесь анализировать. А нужно читать сразу на лету. Если напишете чуточку больше о том, какие данные приходят, то вполне могу помочь написать парсер-автомат, который будет парсить входной поток и распихивать параметры.
Галочка "подтверждения прочтения" - вселенское зло.
min@y™

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

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™

min@y™ (статус: Доктор наук), 20 сентября 2011, 15:24 [#4]:

Цитата (EvgenDRV):

А с парсером на лету было бы здорово.

Ну и чо тебе мешает использовать мою функцию?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
EvgenDRV

EvgenDRV (статус: Посетитель), 20 сентября 2011, 15:46 [#5]:

min@y™: просто что-то разобраться ещё не могу, где проверяется, что x это x? а y это у. В первой строке может быть и x и y и z... и всё что угодно, но нам нужен x...
Пытался сообразить в Вашей функции, что-то туго у меня получается.
min@y™

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

EvgenDRV (статус: Посетитель), 25 сентября 2011, 02:54 [#7]:

спасибо, разобрался, всё отлично работает!
min@y™

min@y™ (статус: Доктор наук), 25 сентября 2011, 10:14 [#8]:

Цитата (EvgenDRV):

спасибо, разобрался, всё отлично работает!

Тогда где мои честные +5 баллов?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:36
Выполнено за 0.05 сек.