Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Подсветка с помощью цикла и SelAttributies

7.4K
02 мая 2009 года
T...H
159 / / 28.12.2008
Здарова программисты!!
Есть простой код:
Код:
for(int i = 1;i<RichEdit1->Text.Length()-1;i++)
{
//-------------------------------------
char S1,S2,S3,S4,S5;
S1 = RichEdit1->Text;
S2 = RichEdit1->Text[i+1];
S3 = RichEdit1->Text[i+2];
if((S1=='f')&&(S2=='o')&&(S3=='r'))
{
RichEdit1->SelStart = i-1;
RichEdit1->SelLength = 3;
RichEdit1->SelAttributes->Color = clRed;
}
//-------------------------
}

данный код очень простой, который подсвечивает слово for красным цветом.
Вопрос: можно через этот способ сделать так. чтобы подсвечивалось вводимое слово, типа ввёл int и подсветился int.
Ведь char-ы должны отсюда создаваться динамически, взависимости от того, насколько длинное слово, а во вторых, что ещё сложнее, ввести их в цикл... :)
294
02 мая 2009 года
Plisteron
982 / / 29.08.2003
Вместо S1, S2, S3 используй, например [COLOR=Black]char s[max_length+1];[/COLOR], где max_length -- максимально допустимая длина подсвечиваемого слова. Или std::array <char> s;, или std::list <char> s; (что больше нравится). В первом случае (char s[]) можно проверять на "подсвечиваемость" с помощью strncmp();
А можно не морочить себе голову, использовать AnsiString и искать подсвечиваемые слова с помощью метода AnsiString::Pos()
1
02 мая 2009 года
kot_
7.3K / / 20.01.2000
Цитата: T...H
Здарова программисты!!
Есть простой код:
Код:
for(int i = 1;i<RichEdit1->Text.Length()-1;i++)
{
//-------------------------------------
char S1,S2,S3,S4,S5;
S1 = RichEdit1->Text;
S2 = RichEdit1->Text[i+1];
S3 = RichEdit1->Text[i+2];
if((S1=='f')&&(S2=='o')&&(S3=='r'))
{
RichEdit1->SelStart = i-1;
RichEdit1->SelLength = 3;
RichEdit1->SelAttributes->Color = clRed;
}
//-------------------------
}

данный код очень простой, который подсвечивает слово for красным цветом.
Вопрос: можно через этот способ сделать так. чтобы подсвечивалось вводимое слово, типа ввёл int и подсветился int.
Ведь char-ы должны отсюда создаваться динамически, взависимости от того, насколько длинное слово, а во вторых, что ещё сложнее, ввести их в цикл... :)


Код:
TStringList *ListAnalis = new TStringList;
ListAnalis->Delimiter = ' ';
 int counter = 0;
 for(int i = 0;i < reList->Lines->Count;++i){
  ListAnalis->Clear();
  ListAnalis->DelimitedText = reList->Lines->Strings;
  for(int j=0;j < ListAnalis->Count;++j ){
   if(ListAnalis->Strings[j].Pos("for")
      ||ListAnalis->Strings[j].Pos("foR")
      || ListAnalis->Strings[j].Pos("For")
      || ListAnalis->Strings[j].Pos("fOr")
      || ListAnalis->Strings[j].Pos("FOR") ){
    ShowMessage("O!!! Це дило! Всего найдено " + IntToStr(++counter));
   }
  }
 }
 delete ListAnalis;

Как получить, на основании этого кода, позицию в строке, я оставляю вам на самостоятельную работу. Тем более что сложного тут ничего нет - достаточно просто убрать один цикл. :)
1
02 мая 2009 года
kot_
7.3K / / 20.01.2000
Кстати - подсказка - вовсе нет необходимости перебирать все строки. Это просто как пример. Все делается гораздо проще - если посветку надо сделать при вводе
294
02 мая 2009 года
Plisteron
982 / / 29.08.2003
Цитата: kot_
 
Код:
if(ListAnalis->Strings[j].Pos("for")
      ||ListAnalis->Strings[j].Pos("foR")


 
Код:
ListAnalis->Strings[j].UpperCase().Pos("FOR");
PS. А мне было лениво писать...
1
02 мая 2009 года
kot_
7.3K / / 20.01.2000
Цитата: Plisteron
 
Код:
ListAnalis->Strings[j].UpperCase().Pos("FOR");
PS. А мне было лениво писать...


ну тогда не совсем. Потому что я показал просто что данная функция зависима от регистра. А приводить скорей всего надо к нижнему регистру - если такая задача стоит.

294
02 мая 2009 года
Plisteron
982 / / 29.08.2003
Цитата: kot_
А приводить скорей всего надо к нижнему регистру - если такая задача стоит.

imho, это дело вкуса -- вести вверх или вниз.

7.4K
02 мая 2009 года
T...H
159 / / 28.12.2008
Цитата:
Как получить, на основании этого кода, позицию в строке, я оставляю вам на самостоятельную работу. Тем более что сложного тут ничего нет - достаточно просто убрать один цикл.


чёт с я не нахожу применения вышеуказанного каода для разных слов.
У меня получилось только для конкретного....

11
02 мая 2009 года
oxotnik333
2.9K / / 03.08.2007
Цитата: T...H
чёт с я не нахожу применения вышеуказанного каода для разных слов.
У меня получилось только для конкретного....


ну как бэ, имелось ввиду в качестве аргумента метода AnsiString::Pos(...) передавать переменную содержащую искомое слово

1
02 мая 2009 года
kot_
7.3K / / 20.01.2000
Цитата: Plisteron
imho, это дело вкуса -- вести вверх или вниз.


причем тут дело вкуса?
в большинстве языков команды fOr нет. И команды FOR тоже.

Цитата:

чёт с я не нахожу применения вышеуказанного каода для разных слов.


и что теперь?

7.4K
02 мая 2009 года
T...H
159 / / 28.12.2008
Цитата:
и что теперь?


следовательно, данный метод не эффективен и не подходит... :)

287
02 мая 2009 года
Shiizoo
958 / / 14.03.2004
Не знаю, как это обычно делается, но когда мне приходилось, я делал это про принципу автомата.

Введи переменную (или набор переменных) для хранения состояния и буфер, для хранения текущей лексемы.
Инициализируй переменные состояния перед перебором текста.
Перебирай текст посимвольно, обрабатывай его в зависимости от переменных состояний и меняй сами эти состояния и содержимое буфера.

Ну а если синтаксис того, для чего делаешь подсветку, позволяет это сделать разбиением по пробельным символам, то и Delemited подойдет.
1
02 мая 2009 года
kot_
7.3K / / 20.01.2000
Цитата: Shiizoo
Не знаю, как это обычно делается, но когда мне приходилось, я делал это про принципу автомата.

Введи переменную (или набор переменных) для хранения состояния и буфер, для хранения текущей лексемы.
Инициализируй переменные состояния перед перебором текста.
Перебирай текст посимвольно, обрабатывай его в зависимости от переменных состояний и меняй сами эти состояния и содержимое буфера.

Ну а если синтаксис того, для чего делаешь подсветку, позволяет это сделать разбиением по пробельным символам, то и Delemited подойдет.


естественно что без использования переменных состояния тут не обойтись - но перебор тут абсолютно не нужен. в моем коде он присутсвует только для организации входящего потока - а все что нужно - контейнер зарезервированных слов и множество по которым можно судить о окончании ввода лексемы (пробел, точка с запятой и пр.). Можно так же и его оформить в контейнер, можно множеством - не суть важно. Контейнер позволит гибче работать - зато множество быстрее.

294
03 мая 2009 года
Plisteron
982 / / 29.08.2003
Цитата: kot_
в большинстве языков команды fOr нет. И команды FOR тоже.


и что теперь? (c) kot_
В исходнике проверяется и на foR, и на FOR. Следовательно, в нём декларируется необходимость проверки Case-Insensitive, и, понятно, чем все комбинации регистров проверять, лучше к одному регистру привести. С точки зрения работы программы, абсолютно по барабану, ListAnalis->Strings[j].UpperCase().Pos("FOR"); или ListAnalis->Strings[j].LowerCase().Pos("for");

Цитата: kot_
Потому что я показал просто что данная функция зависима от регистра.


Я тоже показал. Наличием метода UpperCase(). А ещё в C++ Builder есть Help, в котором вопрошающий может узнать подробности работы AnsiString::Pos().

PS. Извиняюсь за оффтоп.
PPS. Basic, Pascal, PL/SQL -- Case-Insensitive, там могут быть и for, и FOR и любые комбинации регистров (если вдруг программист захочет так оригинально оформить программу).

7.4K
03 мая 2009 года
T...H
159 / / 28.12.2008
ААА!!
А можно как нубудь, как я просил...??
или прийдётся проверять с помощью if каждое
int,long,char и т.п. и отдельно подстраивать код к каждому коду??
:confused:
1
03 мая 2009 года
kot_
7.3K / / 20.01.2000
Цитата: Plisteron
и что теперь? (c) kot_
В исходнике проверяется и на foR, и на FOR. Следовательно, в нём декларируется необходимость проверки Case-Insensitive, и, понятно, чем все комбинации регистров проверять, лучше к одному регистру привести. С точки зрения работы программы, абсолютно по барабану, ListAnalis->Strings[j].UpperCase().Pos("FOR"); или ListAnalis->Strings[j].LowerCase().Pos("for");



Ну и чего ты взъелся?
Еще раз повторяю - это отнюдь не "это дело вкуса", как ты выразился. А определяется языком для которого проводится лексический анализ. В чем я не прав? И кстати конструкции типа ListAnalis->Strings[j].UpperCase().Pos... я предпочел бы
String tmp = ListAnalis->Strings[j].UpperCase();
if(tmp.Pos(... - а еще лучше в блоке подсветки этого не делать - вообще - как бы не соблазнительным это казалось. Если пользователь набрал fOr - то он набрал именно fOr. И если данная лексема не отнесена явно к тем которые надо выделять - то не нужно додумывать за пользователя. Задача подсветки - это задача подсветки а не подсветки и корректировки ввода. Если присутсвует функция корректировки - это ее задача. В данном фрагменте мы должны проверить только не входит ли лексема в пространство заданных - а не модифицировать ввод пользователя. ИМХО.

Цитата:
ААА!!
А можно как нубудь, как я просил...??


можно. могу выдать еще один бан.
Что не понятно? Все что нужно тебе - уже сказано. Остальное делаешь сам.

294
04 мая 2009 года
Plisteron
982 / / 29.08.2003
Цитата: kot_
В чем я не прав?


В том, что в случае Case-Insensitive подсветки не всё равно, к какому регистру приводить. Остальные слова -- увод от темы.

1
04 мая 2009 года
kot_
7.3K / / 20.01.2000
Цитата: Plisteron
В том, что в случае Case-Insensitive подсветки не всё равно, к какому регистру приводить. Остальные слова -- увод от темы.


ни к какому не нужно. надо проверять те словоформы которые есть. Не нужно за пользователя додумывать - что он ввел. Даже если решение кажется удобным. По крайней мере не нужно смешивать в кучу корректировку и анализ.

287
04 мая 2009 года
Shiizoo
958 / / 14.03.2004
Согласен с kot_'ом. Если мне в редакторе в регистрозависимом коде будет подсвечивать ключевые слова в неверном регистре, то это вряд ли будет способствовать выделению ошибки на фоне всего кода. Но если привычка сканировать периферическим зрением подсвеченные слова весьма распространена, надо дать возможность этим людям задействовать такое поведение подсветки. =)

---
А хотя, вот глаза шире открыл. Согласен со всеми, с учетом вновь замеченных оговорок. =)
[quote=Plisteron]...В исходнике проверяется и на foR, и на FOR. Следовательно, в нём декларируется необходимость проверки Case-Insensitive...[/quote]
294
04 мая 2009 года
Plisteron
982 / / 29.08.2003
Цитата: T...H
ААА!!
А можно как нубудь, как я просил...??
или прийдётся проверять с помощью if каждое
int,long,char и т.п. и отдельно подстраивать код к каждому коду??
:confused:


Не плачь.

Код:
AnsiString  Separators("`~!@#$%^&*()_+|-=\\[]{};:\'\",.<>/? ");
    AnsiString  colon(" : ");
    TStrings   *LightLines = memText->Lines;
    TStrings   *Words      = listboxWords->Items;
    int         LinesCount = LightLines->Count;
    int         WordsCount = Words->Count;

    int         LineWidth;
    int         i;
    int         j;
    int         PosBegin;
    int         PosEnd;
    int         wLenght;
    AnsiString  s;
    AnsiString  w0rd;
    AnsiString  wTest;

    for (j = 0; j < LinesCount; j++)
    {
        s = LightLines->Strings[j];
        LineWidth = s.Length();
        PosBegin = 1;
        while (PosBegin <= LineWidth)
        {
            for (i = 0; i < WordsCount && LineWidth; i++)
            {
                w0rd     = Words->Strings;
                wLenght  = w0rd.Length();
                if(wLenght > LineWidth)
                    continue;

                PosEnd   = PosBegin + wLenght - 1;
                wTest    = s.SubString(PosBegin, wLenght);
                if ( (wTest == w0rd) &&
                     (PosEnd >= LineWidth || Separators.Pos(s[PosEnd])) )
                {
                    // Нашли!
                    memPos->Lines->Add(AnsiString(j) + colon + w0rd + colon + AnsiString(PosBegin) + colon + AnsiString(wLenght));
                }
            } // <<< for (i = 0; i < WordsCount && LineWidth; i++)
            PosBegin++;
        } // <<< while (PosBegin <= LineWidth)
    } // <<< for (j = 0; j < LinesCount; j++)
memText -- Memo с текстом (у тебя будет, соответственно, RichEdit)
listboxWords -- листбокс со словами, которые нужно подстветить в тексте
memPos -- Memo, в которое я складываю найденные позиции подлежащих подсветке слов

Особо код на ошибки не тестировал, знаю только, что он компилируется.

Цитата: Shiizoo
Согласен со всеми, с учетом вновь замеченных оговорок. =)


:)) :))

294
06 мая 2009 года
Plisteron
982 / / 29.08.2003
Запустил TOAD, полюбовался, и вспомнил тему case insensitive подсветки.
Цитата: kot_
Еще раз повторяю - это отнюдь не "это дело вкуса", как ты выразился. А определяется языком для которого проводится лексический анализ. В чем я не прав? И кстати конструкции типа ListAnalis->Strings[j].UpperCase().Pos... я предпочел бы
String tmp = ListAnalis->Strings[j].UpperCase();
if(tmp.Pos(... - а еще лучше в блоке подсветки этого не делать - вообще - как бы не соблазнительным это казалось. Если пользователь набрал fOr - то он набрал именно fOr.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог