Analizing characters in a String

New to FreeBASIC? Post your questions here.
Post Reply
atreiooo
Posts: 14
Joined: Jul 31, 2010 12:41
Location: IT

Analizing characters in a String

Post by atreiooo »

Hello to All,
Sorry for my trivial question, but i' m a beginner in programming.
I'm working around a long printable string and i have to find some particular substring composed only by numbers "0..9", characters "A...Z" or "a...z" and not any other characters.
Could someone suggests which is the best way to do that?
Thanks. Enrico
Last edited by atreiooo on Nov 19, 2011 14:19, edited 2 times in total.
Gonzo
Posts: 722
Joined: Dec 11, 2005 22:46

Post by Gonzo »

int position = instr(string, "search")

http://www.freebasic.net/wiki/wikka.php ... KeyPgInstr
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Post by counting_pine »

Unfortunately instr only allows you to search for an exact match. You can do something like this though:

Code: Select all

function isalphanum(byval char as integer) as integer
 '' return -1 for char alphanumeric, 0 otherwise

 select case as const char
 case asc("0") to asc("9"), asc("A") to asc("Z"), asc("a") to asc("z")
  return -1
 end select

 return 0

end function


function scanfor(byref s as const string, byval start as integer = 1, byref length as integer = 0) as integer
 '' scan s for alphanumeric string, return length in third parameter

 dim as integer i = start, n = len(s)

 do
  if i > n then return 0
  if isalphanum(asc(s, i)) then exit do
  i += 1
 loop

 start = i

 do
  if i > n then exit do
  if not isalphanum(asc(s, i)) then exit do
  i += 1
 loop

 length = start - i + 1
 return start
 
end function
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Post by srvaldez »

an elegant solution counting_pine, but for a beginner it might be frightening complex, here's a very simplistic approach.

Code: Select all

dim as string mask = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmopqrstuvwxyz"
dim as string st = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.abcdefghijklmopqrstuvwxyz"
dim as integer i

for i=1 to len(st)
    if instr(mask,mid(st,i,1))=0 then
        print "found "+""""+mid(st,i,1)+""" at position ";i
    end if
next

sleep
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Post by counting_pine »

If you don't want to find the length of the substring, then you could find the first matching character with something like:
instr([start,] s, any "0...9A...Za...z")

(The 'any' string is truncated for readability, not using fancy regular expressions or anything; it would look like the mask in srvaldez's code.)
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Post by srvaldez »

good tip counting_pine :)
atreiooo
Posts: 14
Joined: Jul 31, 2010 12:41
Location: IT

Post by atreiooo »

I thank all that helped, Enrico
atreiooo
Posts: 14
Joined: Jul 31, 2010 12:41
Location: IT

Post by atreiooo »

It's me again with a smal question, but hard for me.
When i save my string in a file (and i use : Write #f, my-string), in the file i find a " " " (quotation mark) as the very first and the last character.
The quotation mark is not present in the string and i think it is the write operation to generate them.
How can i avoid that noisy insertion?
Thanks for your replay.
Enrico
Mihail_B
Posts: 273
Joined: Jan 29, 2008 11:20
Location: Romania
Contact:

Post by Mihail_B »

atreiooo wrote:It's me again with a smal question, but hard for me.
When i save my string in a file (and i use : Write #f, my-string), in the file i find a " " " (quotation mark) as the very first and the last character.
The quotation mark is not present in the string and i think it is the write operation to generate them.
How can i avoid that noisy insertion?
Thanks for your replay.
Enrico
Instead of "write" use "print"

Code: Select all

dim as string a
dim as string b

a= "hello file world"

open "Readme222.txt" for output as #1
print #1,a 
print #1,a;" <-second"
close #1

open "readme222.txt" for input as #1
line input #1,b
print b
line input #1,b
print b
close #1
sleep
to print a text file until it ends you can do this :

Code: Select all

dim as string a,filename

line input "Filename (and path):",filename
if filename="" then 
  print "no file"
  beep
   end
endif


open filename for input as #1
while not eof(1)
  line input #1,a
  print a
wend
close #1
sleep
atreiooo
Posts: 14
Joined: Jul 31, 2010 12:41
Location: IT

Post by atreiooo »

Mihail_B, i thank you very mutch
Enrico
thrive4
Posts: 72
Joined: Jun 25, 2021 15:32

Re: Analizing characters in a String

Post by thrive4 »

Riffing on the code of counting_pine

Code: Select all

' check if string contains alphanumeric value
' courtesy counting_pine https://www.freebasic.net/forum/viewtopic.php?p=166250&hilit=isalphanum#p166250 
function isalphanumeric(haystack as string) as boolean
    dim i as integer
    do
        select case asc(mid(haystack, i, 1))
            case asc("0") to asc("9"), asc("A") to asc("Z"), asc("a") to asc("z")
            return true
        end select
        i += 1
    loop until i > len(haystack)

    return false

end function
UEZ
Posts: 988
Joined: May 05, 2017 19:59
Location: Germany

Re: Analizing characters in a String

Post by UEZ »

I would suggest learning regular expressions for this kind of task. I know it's not easy to learn, but you can more easily perform complex string operations.

Example:

Code: Select all

#Include "pcre.bi"

Function RegEx(Byval aPattern As String, Byval aSubject As String, aArr() As String) As Integer
  Const OVECCOUNT = 300
  
  Dim As Zstring Ptr error_
  Dim As Long error_offset, rc, i, ovector(OVECCOUNT - 1), result
  Dim As pcre Ptr re
  
  Erase aArr
  result = 0
  
  re = pcre_compile(aPattern, 0, @error_, @error_offset, NULL)
  If re = NULL Then
    Return result
  End If
  
  i = 0
  Do
    rc = pcre_exec(re, NULL, Strptr(aSubject), Len(aSubject), i, 0, @ovector(0), OVECCOUNT)
    If rc > 0 Then
      Redim Preserve aArr(Lbound(aArr) To Ubound(aArr) + 1)
      aArr(Ubound(aArr)) = Mid(aSubject, ovector(0) + 1, ovector(1) - ovector(0))
      result += 1
      i = ovector(1)
    End If
  Loop While rc >= 0

  Return result
End Function

Sub PrintArray(aArr() As String)
  For i As Integer = Lbound(aArr) To Ubound(aArr)
    Print(Trim(aArr(i), Any Chr(10, 13, 32)))
  Next i
End Sub


Dim As String aResult(), sPathWindows, sPathLinux

sPathWindows = "c:\Windows\System32\catroot\{127D0A1D-4EF2-11D1-8608-00C04FC295EE}\Test.txt"
RegEx("[A-Za-z0-9]+", sPathWindows, aResult())
PrintArray(aResult())
Sleep
This will extract the words from the string according your criteria and output should be:

Code: Select all

c
Windows
System32
catroot
127D0A1D
4EF2
11D1
8608
00C04FC295EE
Test
txt
If you need libpcre.a you can download it from here: viewtopic.php?f=17&t=19095&start=495#p278794
Post Reply