roboforum.ru

Технический форум по робототехнике.

 

Алгоритм - Фильтр данных из массива [микро Си]

Автомат, адаптивный автомат ... разум

Алгоритм - Фильтр данных из массива [микро Си]

Сообщение redcat » 01 фев 2009, 13:40

Вот вчера понадобилось измассива символов (строки) выделить один или два фрагмента разделяемых символами конца строки и переноса каретки (\r\n) в другие два массива. Что у меня получилось, привожу ниже. Всё работает. Меня интересуют другие варианты подобного фильтрования, но без использования стандартных функций (типа trim(), length()), всё должно компилироваться для микроконтроллера, например на WinAVR.



Код: Выделить всёРазвернуть
 
#include <stdlib.h> // Если не вписать..
#define F_CPU 4 // ...эти две строки
//то на форуме код будет отображаться криво (скрипт не видит что это Код СИ)

char buffer[] = "\r\nMEMORY_FULL\r\n\r\nERROR\r\n"; //Строка в буффере из которой
//нужно получить состояние (сейчас это будет "ERROR")
//и описание состояния (сейчас это описание ошибки "MEMORY_FULL")

char info1[32]; // Сюда нужно поместить описание состояния
//(в конце программы тот должно быть "MEMORY_FULL"

char status1[10];// Сюда нужно поместить состояние
//(в конце программы тот должно быть "ERROR"


////////////////////////////////
void filtr(char *tmpch){ //Функция ФИЛЬТР, в неё передаём массив который нужно отфильтровать
int ind=0;
intcc=0;
int*m; // указатель для my_memo[]
intmy_memo[4]={-1,-1,-1,-1}; //Хранилище номеров первого и последнего символа для каждого слова в массиве
char *s;
m=&my_memo[0]; // Указываем на адрес первой ячейки в массиве
while(*tmpch){ //перебираем массив buffer[]

if((*tmpch != '\r')&&(*tmpch != '\n')&&(*tmpch != '\0')){ //Если текущий символ не \0 \r \n

if(ind==0){ *m++=cc; ind=1;} // и если он первый то добавляем
//его порядковый номер в my_memo[]
//устанавливаем ind=1; Пока ind=1 то в my_memo[0] ничего не записываем
}else{
//Если это любой символ из \0 \r \n
if(ind==1){ *m++ = (cc-1); } // И если в my_memo[] была запись номера первого символа
// Записываем в следующую ячейку my_memo[] номер последнего символа слова
//(фактически это номер первого символа разделителя \r минус 1)
ind=0; // разрешаем новую запись в my_memo[] если попадается символ слова
}
cc++; // Инкреминируем порядковый номер символа в buffer[]
*tmpch++; //перемещаем указатель
}
if(ind==1){ *m=cc-1; } // Если последний символ слова не отмечен
//(в случае когда в конце строки в буффере нет символов разделителей \r\n)
////////////
// заполняем массивы info1[] status1[] в зависимости от номеров в my_memo[]
if(my_memo[0]!=-1 && my_memo[1]!=-1 && my_memo[2]!=-1 && my_memo[3]!=-1 ){
//Если my_memo[] заполнен полностью, т.е есть и состояние и описание
cc=0;
for (int tmp=my_memo[2];tmp<=my_memo[3];tmp++){
status1[cc++]=rx_buffer[tmp];
}
cc=0;
for (int tmp=my_memo[0];tmp<=my_memo[1];tmp++){
info1[cc++]=rx_buffer[tmp];
}


}else if(my_memo[0]!=-1 && my_memo[1]!=-1){// если в my_memo[] "координаты" только одного слова из строки
//т.е. состояние без его описания (например buffer[] = "READY\r\n";)
cc=0;
for (int tmp=my_memo[0];tmp<=my_memo[1];tmp++){
status1[cc++]=rx_buffer[tmp];
}

}

int main(void){

filtr(buffer);
//После вызова функции массивы info1 и status1 содержат
//info1[] = MEMORY_FULL
//status1[] = ERROR

buffer[] = "READY\r\n"; // меняем строку в буффере
filtr(buffer);
//После вызова функции массивы info1 и status1 содержат
//info1[] = "";
//status1[] = READY
}


В общем может ктото предложит другое решение, или оптимизирует это???!!!
Аватара пользователя
redcat
 
Сообщения: 26
Зарегистрирован: 27 янв 2009, 23:39
Откуда: K-Jarve, Estonia
прог. языки: PHP, C.
ФИО: Alex Po

Re: Алгоритм - Фильтр данных из массива [микро Си]

Сообщение Сергей » 01 фев 2009, 13:57

Извини, но это фарш какойто, приведи код в порядок.
Сергей
 
Сообщения: 3741
Зарегистрирован: 29 дек 2004, 23:15
Откуда: Санкт-Петербург
прог. языки: C, C++, C#, Asm
ФИО: Кашликов Сергей

Re: Алгоритм - Фильтр данных из массива [микро Си]

Сообщение redcat » 01 фев 2009, 14:02

Тут трудно красиво код показать. Все табы и лишние пробелы удаляются.
сам код я как смог прокомментировал.
Аватара пользователя
redcat
 
Сообщения: 26
Зарегистрирован: 27 янв 2009, 23:39
Откуда: K-Jarve, Estonia
прог. языки: PHP, C.
ФИО: Alex Po

Re: Алгоритм - Фильтр данных из массива [микро Си]

Сообщение Сергей » 01 фев 2009, 14:05

Код: Выделить всёРазвернуть
if(ind==0){ *m++=cc; ind=1;}

Вот это что за шняга? Или ты думаешь что каждый раз должны перечитывать весь код, чтобы вспомнить что это за переменные? Ну ладно с табами здесь никак, но уж нормально назвать переменные стоило бы
Сергей
 
Сообщения: 3741
Зарегистрирован: 29 дек 2004, 23:15
Откуда: Санкт-Петербург
прог. языки: C, C++, C#, Asm
ФИО: Кашликов Сергей

Re: Алгоритм - Фильтр данных из массива [микро Си]

Сообщение redcat » 01 фев 2009, 14:11

Насчёт названий переменных, это да....
Попробую переписать.
Аватара пользователя
redcat
 
Сообщения: 26
Зарегистрирован: 27 янв 2009, 23:39
Откуда: K-Jarve, Estonia
прог. языки: PHP, C.
ФИО: Alex Po

Re: Алгоритм - Фильтр данных из массива [микро Си]

Сообщение Сергей » 01 фев 2009, 14:14

Найти в инете книгу "С++ для профессионалов. Н.Солтер, С.Клепер", там почитай главу 7 "Кодируем стильно".
Сергей
 
Сообщения: 3741
Зарегистрирован: 29 дек 2004, 23:15
Откуда: Санкт-Петербург
прог. языки: C, C++, C#, Asm
ФИО: Кашликов Сергей

Re: Алгоритм - Фильтр данных из массива [микро Си]

Сообщение =DeaD= » 01 фев 2009, 14:19

Ничего не понял - есть строка с разделителями \n\r и надо из неё извлечь первые 1-2 построки разделённые этими разделителями или как?

Добавлено спустя 4 минуты 7 секунд:
Если да, тогда заведи переменную status=0 и пробегись по строке, меняя статус от текущего символа c[i] каждый раз по правилу:
c[i]=="\n" => status=1
c[i]=="\r" && status==1 => status=2
else => status=0

Если статус=2, тогда можно считать что только что было \n\r и можно либо сразу скопировать подстроку новую, либо записать её начало и конец.
Проект [[Open Robotics]] - Универсальные модули для построения роботов
Аватара пользователя
=DeaD=
 
Сообщения: 24053
Зарегистрирован: 06 окт 2004, 18:01
Откуда: Ебург
прог. языки: Pascal / C++ / PHP / 1C
ФИО: Антон Ботов

Re: Алгоритм - Фильтр данных из массива [микро Си]

Сообщение Сергей » 01 фев 2009, 14:20

Кстати, если говорить о самом коде, где аффтор хочет выделять коды ошибок, - лучше использовать
Код: Выделить всёРазвернуть
const char *errors[] =
{
"ERROR 0",
"ERROR 1",
"ERROR 2",
NULL
}


А потом обращаца по номеру ошибки, чтобы получить ее строковый эквивалент
типа
Код: Выделить всёРазвернуть
char *string = string_new( errors[1] );
Сергей
 
Сообщения: 3741
Зарегистрирован: 29 дек 2004, 23:15
Откуда: Санкт-Петербург
прог. языки: C, C++, C#, Asm
ФИО: Кашликов Сергей

Re: Алгоритм - Фильтр данных из массива [микро Си]

Сообщение redcat » 01 фев 2009, 14:33

Вся гадость этой фильтрации в том, что символы \r и \n могут появлятся в фильтруемой строке по разному. И количество слов в строке может быть 1 или 2. Например возможны такие варианты строк -

\r\n1234567890\r\n\r\nERROR\r\n
1234567890\r\n\r\nERROR\r\n
1234567890\r\nERROR\r\n
1234567890\r\nERROR
\r\nERROR\r\n
ERROR\r\n

Вот из этих вариантов нужно выделить в массивы 1234567890 и ERROR
или только ERROR, как в двух последних строках.
Моя функция работает. Но чтото мне она не нравится.
Аватара пользователя
redcat
 
Сообщения: 26
Зарегистрирован: 27 янв 2009, 23:39
Откуда: K-Jarve, Estonia
прог. языки: PHP, C.
ФИО: Alex Po

Re: Алгоритм - Фильтр данных из массива [микро Си]

Сообщение Сергей » 01 фев 2009, 14:58

Погодь с фильтром, а собсно зачем тебе эта функция? Чем тебе мой вариант не подходит?
Сергей
 
Сообщения: 3741
Зарегистрирован: 29 дек 2004, 23:15
Откуда: Санкт-Петербург
прог. языки: C, C++, C#, Asm
ФИО: Кашликов Сергей

Re: Алгоритм - Фильтр данных из массива [микро Си]

Сообщение =DeaD= » 01 фев 2009, 15:08

redcat писал(а):\r\n1234567890\r\n\r\nERROR\r\n

Строго говоря в этой строке 5 слов, разделённые \r\n: пустое, "1234567890", пустое, "ERROR, пустое.

Добавлено спустя 5 минут 11 секунд:
Пусть c[i] - строка, которую разбираем.

i=1; start=0;
if(c[0]!=0)while(c[i]!=0){
if(c[i-1]=='\r' && c[i]=='\n'){
if(i>start+1){ нашли очередное слово c[start..i-2] };
start=i+1;
};
};
Проект [[Open Robotics]] - Универсальные модули для построения роботов
Аватара пользователя
=DeaD=
 
Сообщения: 24053
Зарегистрирован: 06 окт 2004, 18:01
Откуда: Ебург
прог. языки: Pascal / C++ / PHP / 1C
ФИО: Антон Ботов

Re: Алгоритм - Фильтр данных из массива [микро Си]

Сообщение redcat » 01 фев 2009, 16:48

Сейчас попробую развить...
Плохо то, что RAM всего 128 байт
Аватара пользователя
redcat
 
Сообщения: 26
Зарегистрирован: 27 янв 2009, 23:39
Откуда: K-Jarve, Estonia
прог. языки: PHP, C.
ФИО: Alex Po

Re: Алгоритм - Фильтр данных из массива [микро Си]

Сообщение Сергей » 01 фев 2009, 17:58

128 байт? это что за камень такой?
Сергей
 
Сообщения: 3741
Зарегистрирован: 29 дек 2004, 23:15
Откуда: Санкт-Петербург
прог. языки: C, C++, C#, Asm
ФИО: Кашликов Сергей

Re: Алгоритм - Фильтр данных из массива [микро Си]

Сообщение redcat » 01 фев 2009, 18:34

Сергей писал(а):128 байт? это что за камень такой?

))) Это камушек Attiny2313. Под рукой другого нету.

Вот что получилось -
Код: Выделить всёРазвернуть
  char MyString[32]="SYSTEM NOT READY\r\n\r\nERROR\r\n";
  int SubStringStart = 0;
  int SubStringEnd = 0;
  int ItemCounter = 0;

while(MyString[ItemCounter]!=0){

      if(MyString[ItemCounter]=='\r' && MyString[(ItemCounter+1)]=='\n'  ){

        SubStringEnd = (ItemCounter-1);
         
     if(SubStringEnd>SubStringStart){
     //Берём нужные данные из массива MyString от SubStringStart до SubStringEnd
       ;
     // -------------------------
                                        }
        ItemCounter =  ItemCounter+2 ;
        SubStringStart = ItemCounter;


    } else ItemCounter++;


Плохо только то, что в конце каждой подстроки должны быть \r\n
Аватара пользователя
redcat
 
Сообщения: 26
Зарегистрирован: 27 янв 2009, 23:39
Откуда: K-Jarve, Estonia
прог. языки: PHP, C.
ФИО: Alex Po


Вернуться в Алгоритмы

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

Mail.ru counter