| 
| 
 | Вопрос # 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. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |