FreeBasic
Главная
Вход
Регистрация
Среда, 09.10.2024, 09:26Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Поиск в памяти
KattyДата: Понедельник, 26.08.2013, 03:09 | Сообщение # 1
Рядовой
Группа: Пользователи
Сообщений: 3
Репутация: 0
Статус: Offline
Здравствуйте! Я только начала изучать FB и мне стало интересно, как в FB производить поиск в памяти? Например поиск строк в двоичном файле, поиск последовательности байт, поиск последовательности байт с неизвестными байтами.
 
haavДата: Понедельник, 26.08.2013, 09:01 | Сообщение # 2
Генералиссимус
Группа: Администраторы
Сообщений: 1363
Репутация: 49
Статус: Offline
Привет!

В любом случае из файла надо считать в буфер памяти. Алгоритмов поиска много, все зависит от задач. Вот ЗДЕСЬ можно выбрать алгоритм под свою задачу. Реализация на СИ, но даже если с СИ проблема, главное описана теория.

Цитата (Katty)
Например поиск строк в двоичном файле, поиск последовательности байт


Мне ни разу не нужно было производить быстрый поиск строк в больших объемах памяти. Для моих задач вполне подходило:

Используя библиотеку window9
Считывал в память с помощью функции read_datas , преобразовывал в строковой массив с помощью peeks , а искал с помощью встроенной в freebasic функции Instr. Для моих задач скорости вполне хватало.


Для поиска отдельного двоичного символа можно применить сишную функцию memchr . Для сравнения двоичных буферов memcmp. На основе алгоритмов по ссылке выше и даже в совокупности с функциями memchr , memcmp , можно создать очень быстрый поиск. Готовые примеры я не искал, возможно на оф. форуме или на немецком сайте они есть.

Цитата (Katty)
поиск последовательности байт с неизвестными байтами.


Типа поиска по маске (AA..SSS) ? Для этого однозначно надо писать свою реализацию.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
KattyДата: Вторник, 27.08.2013, 09:31 | Сообщение # 3
Рядовой
Группа: Пользователи
Сообщений: 3
Репутация: 0
Статус: Offline
haav, спасибо за ответ. Пойду изучать.
А вот у VB6 есть такая функция Like наподобие регулярных выражений, вот ей можно искать в бинарном файле. А у FB есть что-то подобное?
 
haavДата: Вторник, 27.08.2013, 10:58 | Сообщение # 4
Генералиссимус
Группа: Администраторы
Сообщений: 1363
Репутация: 49
Статус: Offline
Цитата (Katty)
А вот у VB6 есть такая функция Like наподобие регулярных выражений, вот ей можно искать в бинарном файле. А у FB есть что-то подобное?


У FreeBasic есть только функции Instr и InstrRev для поиска подстроки в строке.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
KattyДата: Четверг, 29.08.2013, 08:31 | Сообщение # 5
Рядовой
Группа: Пользователи
Сообщений: 3
Репутация: 0
Статус: Offline
>У FreeBasic есть только функции Instr и InstrRev для поиска подстроки в строке.
А регулярных выражений нет совсем?
 
haavДата: Четверг, 29.08.2013, 10:33 | Сообщение # 6
Генералиссимус
Группа: Администраторы
Сообщений: 1363
Репутация: 49
Статус: Offline
Цитата (Katty)
А регулярных выражений нет совсем?


В самом языке нет. Но можно подключить библиотеку TRE.
Прикрепления: TRE.zip (815.6 Kb)


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
ShadExДата: Суббота, 31.08.2013, 14:25 | Сообщение # 7
Лейтенант
Группа: Проверенные
Сообщений: 51
Репутация: 1
Статус: Offline
Ну, если только простой поиск по маске, то регулярками искать слишком затратно будет, тем более в бинарных файлах...
Лучше wildcard использовать:

Код
Declare Function checkWildcard (wildcard As String, checkStr As String, caseMode As Integer = 0) As Integer

Function repStr (mainStr As String, findStr As String, replaceStr As String) As String
Dim As String retVal
   If mainStr = "" Then Return ""
   If findStr = "" Then Return mainStr

   For i As uInteger = 1 To Len(mainStr)
     If Mid(mainStr, i, Len(findStr)) = findStr Then
       retVal = retVal + replaceStr
       i += Len(findStr)-1
     Else
       retVal = retVal + Chr(mainStr[i-1])
     End If
   Next i
   Return retVal
End Function

Function isAlphanumeric (char As uByte) As Integer
   If char < Asc("0") Then Return 0
   If char < Asc("9") Then Return 1
   If char < Asc("A") Then Return 0
   If char < Asc("Z") Then Return 1
   If char < Asc("a") Then Return 0
   If char < Asc("z") Then Return 1
   Return 0
End Function

Function checkWildcard (wildcard As String, checkStr As String, caseMode As Integer = 0) As Integer
Dim As Integer i = 0, j = 0
Dim As Integer found
Dim As Integer tmp

   'Case mode:  0 = case-insensitive, non-zero = case-sensitive
   If caseMode = 0 Then
     'Case-insensitive just means both strings are converted to lowercase
     'before the wildcard comparison is performed.
     wildcard = LCase(wildcard)
     checkStr = LCase(checkStr)
   End If

   'If the wildcard string is *, return 0 no matter what because it will match
   'anything and everything
   If wildcard = "*" Then Return 1

   'Keep replacing until there's nothing left to replace
   'Turns a run of "*" characters (such as "*****") into a single "*"
   Do
     tmp = Len(wildcard)
     wildcard = repStr(wildcard, "**", "*")
   Loop While Len(wildcard) < tmp

   'Continue as long as there's anything left to both strings
   Do While (i < Len(checkStr)) And (j < Len(wildcard))
     'If we find a ? alphanumeric wildcard
     If wildcard [j]= Asc("?") Then
       'If the next character is not alphanumeric, return mismatch
       If isAlphanumeric(checkStr[i]) = 0 Then
         Return 0
       End If
       'Otherwise, go to the next character in both strings
       i += 1
       j += 1
     'If we find a * wildcard
     ElseIf wildcard [j]= Asc("*") Then
       'If we're at the end of the wildcard string return TRUE
       'because wildcard matches anything that could be beyond.
       If j = Len(wildcard) Then Return 1

       'Otherwise, search the string being checked for the character
       'following the wildcard.
       Do Until checkStr [i]= wildcard[j+1]
         'Skip over every character until we get to that one
         i += 1
       Loop
       'We only skip one character - the wildcard
       j += 1
     'If there's simply a mismatch, return FALSE
     ElseIf wildcard [j]<> checkStr [i]Then
       Return 0
     Else
       'But if it's a regular character which matches in both,
       'skip both characters in both strings
       i += 1
       j += 1
     End If

     'If we reach the end of the wildcard before the main string, return FALSE
     If (i < Len(checkStr)) And (j >= Len(wildcard)) Then Return 0

     'If we reach the end of the main string before the end of the wildcard,
     'check if we're on the last character of the wildcard and if it's a *
     'if either condition is false, return FALSE - otherwise return TRUE.
     If (i >= Len(checkStr)) And (j < Len(wildcard)) Then
       If j = Len(wildcard)-1 Then
         If wildcard [j]= Asc("*") Then Return 1
       End If
       Return 0
     End If
   Loop

   'Anything that has made it to the end like this must be matching
   Return 1
End Function

Dim bin_string as String = Chr(127)+"Сьешь еще этих" +Chr(8)+ "мягких французких булок да выпей чаю."+Chr(10)
bin_string &= Chr(127)+"The quick brown fox" + Chr(127) + "jumps over the lazy dog"

? bin_string
? checkWildcard("*мягких*чаю*the*jump*do?", bin_string)
? checkWildcard("*мягких*чаю*the*jump*do?", bin_string,1)
? checkWildcard("*мягких*чаю*The*jump*do?", bin_string,1)
Sleep

Ну и конечно же это только для однобайтовых кодировок.
 
  • Страница 1 из 1
  • 1
Поиск: