C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Анализ строк, разбор строк
Лена
Отправлено: 15.10.2006, 19:08


Мастер участка

Группа: Участник
Сообщений: 501



Программа генерирует разные строки, в которых функции со своими именами и параметрами. Эти строки помещаются в список CheckBox. Примеры генерируемых строк:
void QueryInterface([in]GUID,[out]void*)
void GetIDsOfNames([in]GUID,[in]char*,[in]unsigned int,[in]unsigned long,[out]long)
unsigned long AddRef()
void FormattedTextRC(long,long,BSTR)
void EditPasteValues()
void GetFont(BSTR,short,VARIANT_BOOL,VARIANT_BOOL,VARIANT_BOOL,VARIANT_BOOL,OLE_COLOR,VARIANT_BOOL,VARIANT_BOOL)
и т.д.

Я, выбирая строчку из списка, должна занести в Edit-ы параметры из строки. Например, для строки: void QueryInterface([in]GUID,[out]void*) надо получить в первый Edit GUID, а во второй Edit занести void*. Для функции void FormattedTextRC(long,long,BSTR) надо занести в три Edit-a соответственно long, long и BSTR.
Подскажите универсальный алгоритм анализа таких строк для получения из них в Edit-ы параметры. Строки такие разные, не соображу, как анализировать. Если бы в некоторых функциях не было бы скобок типа [out], то можно было анализировать по позиции запятой “,”
Хочется получить универсальный алгоритм вычленения параметров из строк такого вида.



Присоединить изображение

Присоединить изображение

Admin
Отправлено: 15.10.2006, 22:51


Владимир

Группа: Администратор
Сообщений: 1190



В C++Builder наверное через методы AnsiString:
Pos(), SubString(), Delete().

1. Все параметры находятся между символами ( и ).
Ищем ( и ) и получаем строку между ними.

2. Все параметры разделены запятыми.
Ищем запятые и получаем всё что между ними.

3. Всё что внутри [] надо удалить. (если они не нужны).
Ищем [ и ] и удаляем их и все что между ними.
Так что идея анализировать по позиции запятой правильная.

Также можно сделать массив строк ключевыx слов(параметров):
"int", "long", "double", "bool" и выполнять проверку после
пункта 2 на наличие этих слов, тогда без пунта 3 можно
обойтись.
beginner
Отправлено: 16.10.2006, 02:14


Дежурный стрелочник

Группа: Участник
Сообщений: 44



Admin так хорошо все расписал, что не мог воздержаться,
чтоб не закодить. smile.gif
CODE
void __fastcall TForm1::Button9Click(TObject *Sender)
{
 AnsiString str = "void GetIDsOfNames([in]GUID,[in]char*,[in]unsigned int,[in]unsigned long,[out]long)";


 TStringList *stl = new TStringList();
 char buf[512];
 strcpy(buf, str.c_str());
 char *chbeg = strchr(buf, '(') + 1;
 char *chend = strchr(chbeg, ')');
 *chend = '\0';
 while(chbeg < chend)
 {
   if(*chbeg=='[')chbeg = strchr(chbeg, ']') + 1;
   char *ch = strchr(chbeg, ',');
   if(ch==NULL)
     ch = chend;
   else
     *ch = '\0';
   stl->Add(Trim((AnsiString)chbeg));
   chbeg = ch + 1;
 }
 for(int i=0;i<stl->Count; i++)
   ShowMessage(stl->Strings[i]);
}
Лена
Отправлено: 16.10.2006, 09:46


Мастер участка

Группа: Участник
Сообщений: 501



Cпасибо за подробный ответ.
Что касается кода, то попалась функция для которой этот код не доробатывает:
void OLESetData([in][out]DataObject**,[in][out]short*).
Еще я добавила в конце delete stl; т.к. там, в начале есть new.

Отредактировано Лена — 16.10.2006, 11:29
beginner
Отправлено: 16.10.2006, 18:05


Дежурный стрелочник

Группа: Участник
Сообщений: 44



На счет нескольких блоков[], Admin явно не доработал. wink.gif
SQL
void __fastcall TForm1::Button9Click(TObject *Sender)
{
AnsiString str = "void GetIDsOfNames([in]GUID,[in]char*,[in]unsigned int,[in]unsigned long,[out]long)";


TStringList *stl = new TStringList();
char buf[512];
strcpy(buf, str.c_str());
char *chbeg = strchr(buf, '(') + 1;
char *chend = strchr(chbeg, ')');
*chend = '<!--POST BOX-->';
while(chbeg < chend)
{
while(*chbeg=='[')chbeg = strchr(chbeg, ']') + 1; // Да, здесь был баг. sad.gif
char *ch = strchr(chbeg, ','); // И даже незнаю на кого валить. smile.gif
if(ch==NULL)
ch = chend;
else
*ch = '<!--POST BOX-->';
stl->Add(Trim((AnsiString)chbeg));
chbeg = ch + 1;
}
for(int i=0;i<stl->Count; i++)
ShowMessage(stl->Strings[i]);
delete stl;
}


Отредактировано beginner — 17.10.2006, 15:29
Лена
Отправлено: 17.10.2006, 10:25


Мастер участка

Группа: Участник
Сообщений: 501



Большое спасибо. Работает. smile.gif
Я только добавила знак разыменования в строке:
while(chbeg=='[') на while(*chbeg=='[') иначе не компилировалось.


Вернуться в Вопросы программирования в C++Builder