Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Глюки с pos, почему не работает поиск подстроки 
:(
    Опции темы
Herzog
Дата 10.11.2009, 11:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 6.11.2007

Репутация: нет
Всего: нет



Задача:
Cbuilder6 Найти и заменить в тексте файла указанную подстроку на подстроку


1. На форме есть стандартный RichEdit::RichFile.
2. Глобальные переменные подстроки  поиска и замены - AnsiString FindStr, ReplaceStr;
3. Читаю файл (или его кусок - исходя из размера) в RichFile->Lines->LoadFrom File
4. в функции локальная переменная int pos;
5. заменяю:
Код
    while( pos = RichFile->Text.Pos(FindStr) )
    {
        RichFile->Text.Delete( pos, FindStr.Length() );
        RichFile->Text.Insert( ReplaceStr, pos );
    }

вот тут и не работает - до замены дело не доходит, в цикл не входит ни разу, несмотря на то, что совпадение есть точно! Т.е не работает .Pos

В описании Pos параметр должен быть const AnsiString, но я прямо указать его не могу, т.к. подстроки поиска и замены переменные, вводятся юзером. 
Если и заменить Pos - то чем?

С уважением,
Herzog 


Модератор: не забываем пользоваться кнопочкой "Код"

Это сообщение отредактировал(а) bsa - 10.11.2009, 12:24
PM MAIL   Вверх
bsa
Дата 10.11.2009, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: нет
Всего: 196



pos = RichFile->Text.Pos(FindStr) - это присвоить pos, значение RichFile->Text.Pos(FindStr). Ты уверен, что тебе именно это нужно? Может тебе нужен оператор сравнения (==)?
PM   Вверх
Herzog
Дата 10.11.2009, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 6.11.2007

Репутация: нет
Всего: нет



Цитата(bsa @ 10.11.2009,  12:26)
pos = RichFile->Text.Pos(FindStr) - это присвоить pos, значение RichFile->Text.Pos(FindStr). Ты уверен, что тебе именно это нужно? Может тебе нужен оператор сравнения (==)?

Да, уверен.

У меня длинный текстовый файл, в котором нужно найти множество подстрок, аналогичных введенной юзером и запомненной в FindStr и заменить на им же введенную ReplaceStr. 
Для этого мне нужно находить положение очередного совпадения по индексу. 

Собственно можно было бы провернуть все это в текстовом редакторе, но часть замен может быть - на неотображаемые символы (LineFeed, CarrigeReturn, Tab...)

С уважением,
Herzog  


Это сообщение отредактировал(а) Herzog - 10.11.2009, 13:26
PM MAIL   Вверх
Данкинг
Дата 10.11.2009, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Yersinia pestis
****


Профиль
Группа: Завсегдатай
Сообщений: 8302
Регистрация: 7.11.2006
Где: მოსკოვი

Репутация: 11
Всего: 130



Herzog, а если переделать алгоритм? Я бы проходил по строкам RichEdit'а и в каждой из них искал бы нужную подстроку. По-моему, так будет более логично. smile 


--------------------
There's nothing left but silent epitaphs.
PM MAIL WWW   Вверх
xvr
Дата 10.11.2009, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



В цикл входить должно, а вот замена работать не будет. RichFile->Text - это проперть, и что бы ее заменить в нее надо записать. Ты же меняешь часть КОПИИ строки, а не саму строку
Код

  while( pos = RichFile->Text.Pos(FindStr) )
    {
        AnsiString text= RichFile->Text;
        text.Delete( pos, FindStr.Length() );
        text.Insert( ReplaceStr, pos );
        RichFile->Text = text;
    }

PM MAIL   Вверх
Herzog
Дата 10.11.2009, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 6.11.2007

Репутация: нет
Всего: нет



Цитата(Данкинг @ 10.11.2009,  13:11)
Herzog, а если переделать алгоритм? Я бы проходил по строкам RichEdit'а и в каждой из них искал бы нужную подстроку. По-моему, так будет более логично. smile

У меня строк в RichEdit'е как таковых нет.
Файл представлет собой протокол обмена компи с внешней микроконтроллерной схемой. Просто груда печатных символов - результат протоколирования работы микроконтроллера за долгий промежуток времени.
Для компи этот объем слитный, т.к. приходится экономить на скорости передачи лишних символов, а вот для поиска ошибок отладки мне нужно представить его в читаемом виде - вставить перевод строки, выделить повторяющиеся куски... и т.д.

Програмка в которой у меня сейчас затык - вспомогательная для отладки и не очень хочется тратить время на написание процедуры сравнения и замены поиндексно двух AnsiString - тем более, что есть стандартная функция.
Только не работает почему-то.

C уважением,
Herzog

Добавлено через 7 минут и 25 секунд
Цитата(xvr @ 10.11.2009,  13:31)
В цикл входить должно, а вот замена работать не будет. RichFile->Text - это проперть, и что бы ее заменить в нее надо записать. Ты же меняешь часть КОПИИ строки, а не саму строку
Код

  while( pos = RichFile->Text.Pos(FindStr) )
    {
        AnsiString text= RichFile->Text;
        text.Delete( pos, FindStr.Length() );
        text.Insert( ReplaceStr, pos );
        RichFile->Text = text;
    }

RichEdit глобален для функции сравнения. 
Проверил - могу без проблем менять его в рамках функции, где провожу замену.

Но дело не в этом - не захожу в цикл, т.к. значение pos = 0 Т.е. не находится очевидное, гарантированное вхождение подстроки.
Пред самим циклом я ставлю печать как и RichFile->Text, так и FindStr. Они есть и вхождение тоже должно быть.

С уважением,
Herzog 
PM MAIL   Вверх
mrbrooks
Дата 10.11.2009, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



 
Цитата(Herzog @  10.11.2009,  13:35 Найти цитируемый пост)
Файл представлет собой протокол обмена компи с внешней микроконтроллерной схемой.

непосредственно кто опрашивает данную систему - твой софт или сторонний. Если твой - то гораздо удобнее сразу записывать информацию в файл, ибо к тебе приходит по любому стандартный пакет из байт. Не составляет труда из этого буфера выудить необходимую информацию и поместить ее в хранилище данных. А парсить то куда все валом падает не есть айс.
PM MAIL   Вверх
Herzog
Дата 10.11.2009, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 6.11.2007

Репутация: нет
Всего: нет



Цитата(mrbrooks @ 10.11.2009,  13:55)
Цитата(Herzog @  10.11.2009,  13:35 Найти цитируемый пост)
Файл представлет собой протокол обмена компи с внешней микроконтроллерной схемой.

непосредственно кто опрашивает данную систему - твой софт или сторонний. Если твой - то гораздо удобнее сразу записывать информацию в файл, ибо к тебе приходит по любому стандартный пакет из байт. Не составляет труда из этого буфера выудить необходимую информацию и поместить ее в хранилище данных. А парсить то куда все валом падает не есть айс.

Не важно это...

Да, мой софт и на микроконтроллере и в связной программе приема рзультата протоколирования.
Я принимаю данные, разбираю их, сортирую  и сбрасываю обработанный результат на диск. 

Но сейчас я на стадии отлаживания протокола обмена. Принимаю данные скопом и сбрасываю на диск. А что бы найти ошибки - редко и случайно возникающие ошибки передачи, хочу проанализировать эту кучу, представив ее в виде построчных записей.

Не решайте за меня всю задачу - я прошу помощи лишь разобраться с глюками стандартного ансистринга.

С уважением,
Herzog 
PM MAIL   Вверх
xvr
Дата 10.11.2009, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата

Не решайте за меня всю задачу - я прошу помощи лишь разобраться с глюками стандартного ансистринга.
А придется - нету у стандартного AnsiString'а таких глюков. Pos все замечательно ищет. Так что ищи ошибку у себя. Например в FindStr что то не то. В частности - нет ли там каких непечатаемых символов? Вообще использовать RichText для промежуточного хранения данных не самая лучшая идея - он внутри себя все хранит в RTF формате, и при чтении и записи проперти Text делает перевод в/из RTF. Так что результат чтения из Text может не совпасть с тем, что в нее писали.
Цитата

Проверил - могу без проблем менять его в рамках функции, где провожу замену.
Да ради бога, меняй. Но результата от RichFile->Text.Delete( pos, FindStr.Length() ); не будет, RichFile->Text останется неизменным

PM MAIL   Вверх
Herzog
Дата 10.11.2009, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 6.11.2007

Репутация: нет
Всего: нет



Цитата(xvr @ 10.11.2009,  14:29)
Цитата

Не решайте за меня всю задачу - я прошу помощи лишь разобраться с глюками стандартного ансистринга.
А придется - нету у стандартного AnsiString'а таких глюков. Pos все замечательно ищет. Так что ищи ошибку у себя. Например в FindStr что то не то. В частности - нет ли там каких непечатаемых символов? Вообще использовать RichText для промежуточного хранения данных не самая лучшая идея - он внутри себя все хранит в RTF формате, и при чтении и записи проперти Text делает перевод в/из RTF. Так что результат чтения из Text может не совпасть с тем, что в нее писали.
Цитата

Проверил - могу без проблем менять его в рамках функции, где провожу замену.
Да ради бога, меняй. Но результата от RichFile->Text.Delete( pos, FindStr.Length() ); не будет, RichFile->Text останется неизменным

Цитата
он внутри себя все хранит в RTF формате, и при чтении и записи проперти Text делает перевод в/из RTF
Меня сейчас не волнуют его личные форматы хранения - перед while( .pos) я ставил ShowMessage( RichFile->Text ) и убеждался что он преобразовался до стринга в нормальном и предсказуемом для меня виде. И FindStr тоже печатал для контроля - все ОК.

Почему вот не работает Pos? Видимо только с constat стрингами. Хотя это уже чисто спортивный вопрос, т.к. буксовать на ровном месте мне уже поднадоело и времени нет разбираться - я, видимо, напишу свою процедуру сравнения.

А что до RichEdit - попробовал. Он изменяется, но пусть Вас это не беспокоит - считаете его вне зоны видимости, можете продолжать считать так и дальше.

С уважением,
Herzog 

Это сообщение отредактировал(а) Herzog - 10.11.2009, 14:41
PM MAIL   Вверх
xvr
Дата 10.11.2009, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата

Меня сейчас не волнуют его личные форматы хранения
А зря - он вполне может изуродовать вашу строку как бог черепаху  smile 
Еще мне не понятно - почему именно RichEdit? Чем не угодил обычный TMemo - он точно строки не обрабатывает внутри себя

Цитата

перед while( .pos) я ставил ShowMessage( RichFile->Text ) и убеждался что он преобразовался до стринга в нормальном и предсказуемом для меня виде.

Вы пытались отладчиком пройти по циклу while? Вы пытались отладчиком посмотреть содержимое RichFile->Text и FindStr? Печатать их для контроля через ShowMessage совершенно недостаточно - ShowMessage может вам не показать непечатаемые символы, которые есть в одной строке но нету в другой.

Цитата

Почему вот не работает Pos? Видимо только с constat стрингами. 
Он работает с ЛЮБЫМИ стрингами.

Цитата

Хотя это уже чисто спортивный вопрос, т.к. буксовать на ровном месте мне уже поднадоело и времени нет разбираться - я, видимо, напишу свою процедуру сравнения.
Валяйте пишите. Видимо это новый стиль написания программ - не умею пользоваться чем то - напишу свое.

Цитата

А что до RichEdit - попробовал. Он изменяется, но пусть Вас это не беспокоит - 
А, т.е. в while вы все таки зашли? Или это ваши домыслы? Можно пример кода?
Цитата

считаете его вне зоны видимости, можете продолжать считать так и дальше.
Вы вообще читали, что я вам писал? Причем здесь 'зона видимости'? Я писал, что вызов RichFile->Text.Delete не изменит RichFile->Text. Не верите - к терапевту.


PM MAIL   Вверх
Usper
Дата 10.11.2009, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 13.4.2007

Репутация: 15
Всего: 15



Как уже было сказано, функции Delete() и Insert() не модифицируют строку, а возвращают значение (так написано в справке, но в книжке Архангельского с точностью до наоборот) поэтому:
Код
while( pos = RichFile->Text.Pos(FindStr) )
    {
        RichFile->Text=RichFile->Text.Delete( pos, FindStr.Length());
        RichFile->Text=RichFile->Text.Insert( ReplaceStr, pos );
    }




--------------------
На посохе волшебном нехилый набалдашник, большой такой, огромный, нехилый набалдашник.
PM MAIL   Вверх
Herzog
Дата 10.11.2009, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 6.11.2007

Репутация: нет
Всего: нет



Спасибо, Вы написали ответ, когда я уже и сам - по Вашей подсказке - нашел ошибку.

Нет, я не использовал отладчик. Просто вывел на печать посимвольно в hex формате каждый байт RichFile->Text:
 
Код

          buf = "";
            for( i = 1; i <= RichFile->Text.Length(); i++ )
            {
                s = IntToHex( RichFile->Text[i], 2 );
                buf += s;
                buf += '\t';
                if( !(i % 30) )
                    buf += '\n';
            }
           Msg( buf );

и увидел rtf-овскую фигню. Каждый байт моих данных отображался в виде двухбайтного числа расширенной кодировки, не считая служебного блока кодов установки стилей и шрифтов в начале файла (точнее - моей пседвостринговской строки). 
Разумеется, сравнивая их с "чистым" стрингом, я не находил совпадений.
Showmessage() ничего не показал, т.к. преобразовывал rtf обратно в стринговский вид.

Что касается проверки доступности Rich'а - в цикл еще не попал (а сейчас и подавно не буду, поскольку придется поменять кое-что), а перед циклом загонял туда другое значение и все работало.

Самое главное не в том, что я разобрался в отладочной программе - похожие, только более серьезные ошибки с Rich'ами подждали меня в моей сервисной программе связи.


Спасибо, xvr, за пинок в нужном направлении.
Спасибо всем, кто был внимателенен ко мне и хотел помочь.

P.S. К Rich'ам я привык, давно, еще когда писал программу для жены - тесты по французскому языку. Там везде диакритические значки (крышечки и хвостики над и под буквами), не передаваемые в других окнах, кроме Rich'а. 
Привык....

До свидания,
Herzog  

Это сообщение отредактировал(а) Herzog - 10.11.2009, 15:51
PM MAIL   Вверх
Herzog
Дата 10.11.2009, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 6.11.2007

Репутация: нет
Всего: нет




С этим разберусь - дойдет ход.
Сейчас хотелось бы чисто шкурный вопрос - не подскажите, где достать электронную версию Архангельского, но не ввиде картинки сканированного текста (таких у меня два варианта уже есть). Чтобы можно было ввести поиск по словам.
Иначе пользоваться крайне неудобно.

С уважением,
Herzog 

Это сообщение отредактировал(а) Herzog - 10.11.2009, 16:22
PM MAIL   Вверх
xvr
Дата 10.11.2009, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Небольшой совет - форматирование строк лога с устройства лучше делать прямо на лету, ДО помещения их в RichEdit (или любой другой Edit)

Добавлено через 3 минуты и 40 секунд
Кстати, еще один совет: вот это
Код

while( pos = RichFile->Text.Pos(FindStr) )
    {
        RichFile->Text=RichFile->Text.Delete( pos, FindStr.Length());
        RichFile->Text=RichFile->Text.Insert( ReplaceStr, pos );
    }
лучше делать так
Код

AnsiString text=RichFile->Text;
while( pos text.Pos(FindStr) )
    {
        text=text.Delete( pos, FindStr.Length());
        text=text.Insert( ReplaceStr, pos );
    }
RichFile->Text=text;
т.к. чтение и запись RichFile->Text это ОЧЕНЬ медленная операция, особенно при больших объемах текста в RichEdit


PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0630 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.