How to search for a word in a string in FreeBASIC - basic

I am trying to create an internal function in my FreeBASIC program where i want to check for the word "echo" in the string variable "line0" and if "echo" is part of the string, i want it to echo the input (except "echo")

BASIC's Instr function can search through a string and find out if it contains a certain substring. It can do so starting at the first position of the string or any other position if we mention the value in the parameter list. The result that Instr returns is the character position of the find or else zero to denote that the substring was not found.
It's the optional mentioning of the start position that makes all the difference in writing an algorithm that has to find all occurences of a certain substring.
Once Start = 1 Position = Instr(Start, MyString, MySubString) has found the first substring, we can move the start position to just past the find and start over again. We keep doing so until the Instr function returns zero which tells us there are no more occurences of the substring.
Echo asked: What is this echo that echoes in my ear?
^ ^ ^ ^ ^ ^ ^
1 | | | | | |
+4 5 | | | | |
26 | | | |
+4 30 | | |
36 | |
+4 40 |
0 "Not found"
A function that prints its result directly
This SkipText function expects from 1 to 3 parameters. The second and third parameters are optional because of the mention of a default value in the parameter list.
param1 is the string to search (in)
param2 is the string to search for
param3 can limit the number of removals
Declare Function SkipText (a As String, b As String = "", c As Integer = 1) As Integer
Dim As String s
s = "Echo asked: What is this echo that echoes in my ear?"
Print "The function outputs directly"
Print " Unmodified: ";
SkipText(s)
Print " Modified*1: ";
SkipText(s, "echo", 1)
Print " Modified*2: ";
SkipText(s, "echo", 2)
Print " Modified*3: ";
SkipText(s, "echo", 3)
GetKey ' So you can inspect the output
Function SkipText (a As String, b As String, c As Integer) As Integer
Dim As Integer h, i, j, k
h = IIf(c < 1, 1, c) ' Guard against bogus input
i = 1
j = 1 + Len(a) - Len(b)
Do While i <= j
k = InStr(i, a, b) ' Case-sensitive
If k = 0 Then Exit Do
Print Mid(a, i, k-i);
i = k + Len(b)
h -= 1
If h = 0 Then Exit Do
Loop
Print Mid(a, i)
Return 0
End Function
A function that returns a string that the caller can then print
Next SkipText function expects from 1 to 3 parameters. The second and third parameters are optional because of the mention of a default value in the parameter list.
param1 is the string to search (in)
param2 is the string to search for
param3 can limit the number of removals
If you tried the above code snippet, you will have seen that the first "Echo", the one that starts with a capital, was not removed. This happens because FreeBasic's Instr always works 'case-sensitive'. The simple solution to remove in a 'case-insensitive' way is to use the UCase function like in:
Position = Instr(Start, UCase(MyString), UCase(MySubString))
Declare Function SkipText (a As String, b As String = "", c As Integer = 1) As String
Dim As String s
s = "Echo asked: What is this echo that echoes in my ear?"
Print "The function returns a (reduced) string"
Print " Unmodified: "; SkipText(s)
Print " Modified*1: "; SkipText(s, "echo", 1)
Print " Modified*2: "; SkipText(s, "echo", 2)
Print " Modified*3: "; SkipText(s, "echo", 3)
GetKey ' So you can inspect the output
Function SkipText (a As String, b As String, c As Integer) As String
Dim As String t = ""
Dim As Integer h, i, j, k
h = IIf(c < 1, 1, c) ' Guard against bogus input
i = 1
j = 1 + Len(a) - Len(b)
Do While i <= j
k = InStr(i, UCase(a), UCase(b)) ' Case-insensitive
If k = 0 Then Exit Do
t = t + Mid(a, i, k-i)
i = k + Len(b)
h -= 1
If h = 0 Then Exit Do
Loop
Return t + Mid(a, i)
End Function
() Because these are tiny code snippets, I wasted no time choosing sensible identifiers. In longer programs you should always pick meaningful names for any identifiers.
() FreeBasic comes with a nice, comprehensive manual. If anything isn't clear, first consult the manual, then maybe ask a question on this forum.

did you do any kind of research? Sorry, but I assume you did not.
The answer is, there is already a function for this task builtin in Basic language.
The function you are searching for is "INSTR". Please read the available documentation for FreeBasic. If you then decide to try to write your own INSTR function (if you need a feature which is not provided by the builtin function), try to do your coding, and if you stuck, we´ll try to help.
Your described task will therefore include the following functions:
INSTR ' check if the string is here
LEN ' to know the length of your search string
MID ' to create the 'reduced' output (maybe you will to have it used twice)

Related

Sorting strings without methods and other types

Hello I have to reorder a string, I am banned from using other types and str methods
So my problem is that I could not figure out how to end my code to get it work with any string
I tried to compare the results with sorted() to check and I am stuck at the first exchange
My code:
i = 0
s1 = "hello"
s2 = sorted(s1)
while (i<len(s1)):
j=i+1
while (j<=len(s1)-1):
if (s1[i] > s1[j]):
s1 = s1[0:i] + s1[j] + s1[i]
j+=1
i+=1
print(s1)
print(s2)
I tried to add + s1[len(s1):] at the end of the operation but
I only had found the result for a single string(that I was testing) adding thisI am really stuck, how can I make it work for all the strings with different lenghts??
Thanks
You're not reconstructing the string correctly when doing s1 = s1[0:i] + s1[j] + s1[i] as you're replacing one character for the other but you omit to actually interchange the two and to add the remains of the splitted string to the end of the new string.
Given what your code looks like, I would do it like this:
i = 0
s1 = "hello"
s2 = sorted(s1)
while i < len(s1):
j = i + 1
while j <= len(s1)-1:
if s1[i] > s1[j]:
s1 = s1[0:i] + s1[j] + s1[i+1:j] + s1[i] + s1[j+1:len(s1)]
j += 1
i += 1
print("".join(s2))
# > 'ehllo'
print(s1)
# > 'ehllo'
Please tell me if anything is unclear!
I am banned from using other types and str methods
Based upon your criteria, your request is impossible. Just accessing the elements of a string requires string methods.
The technique that you are using is very convoluted, hard to read and is difficult to debug. Try running your code in a debugger.
Now given that you are allowed to convert a string to a list (which requires string methods), redesign your code to use simple, easy to understand statements.
The following code first converts the string into a list. Then loops thru the list starting at the beginning and compares each following character to the end. If any character is less then the current character, swap. As you step thru the string, the character swaps will result in a sorted list. At the end convert the list back to a string using join().
msg = 'hello'
s = list(msg)
for i in range(len(s) - 1):
for j in range(i + 1, len(s)):
if s[i] <= s[j]:
continue
# swap characters
s[i], s[j] = s[j], s[i]
print(msg)
print(''.join(s))

VBA generate a code

there. I made this code that replaces a character for two number (e.g. 0 = 10; 1 = 11; 2 = 12; ...) and everything works fine except for the first element (the zero element). So, if I put "010a4" string on cell A1 and use my formula "=GENERATECODE(A1)", my expected return value is "1011102014" but I've got a "110111102014" string. So, only zero value occur this error and I can't figured out why. Any thoughts?
My code:
Function GENERATECODE(Code As String)
Dim A As String
Dim B As String
Dim i As Integer
Const AccChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
Const RegChars = "1011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071"
For i = 1 To Len(AccChars)
A = Mid(AccChars, i, 1)
B = Mid(RegChars, 2 * i - 1, 2)
Code = Replace(Code, A, B)
Next
GENERATECODE = Code
End Function
Your problem is that your code first change each 0 to 10 then each 1 to 11. So each 0 give you 10 then 110.
If you want to keep the same kind of algorithm (which might not be a good choice), you need to change AccChars and RegChars so that a character is never replaced by a string that can give a character found later on the AccChars String. In your case just replace Const AccChars = "012 ... per Const AccChars = "102 ... and Const RegChars = "101112 ... per Const RegChars = "111012 ...
But it might be better to change your algorithm altogether. I would first suggest to not use in place editing of the string, but rather to use 2 Strings.
In addition to being incorrect, your current code is inefficient since it involves scanning over the code string multiple times instead of just once. Simply scan over the string once, gathering the substitutions into an array which is joined at the end:
Function GENERATECODE(Code As String) As String
Dim codes As Variant
Dim i As Long, n As Long
Dim c As String
n = Len(Code)
ReDim codes(1 To n)
For i = 1 To n
c = Mid(Code, i, 1)
Select Case c
Case "0" To "9":
codes(i) = "1" & c
Case "a" To "z":
codes(i) = Asc(c) - 77
Case "A" To "Z":
codes(i) = Asc(c) - 19
Case Else:
codes(i) = "??"
End Select
Next i
GENERATECODE = Join(codes, "")
End Function
Example:
?generatecode("010a4")
1011102014
The point of the two offsets is that you want "a" to map to 20 and "A" to map to 46. Note Asc("a") - 77 = 97 - 77 and Asc("A") - 19 = 65-19 = 46.

Getting the largest and smallest word at a string

when I run this codes the output is (" "," "),however it should be ("I","love")!!!, and there is no errors . what should I do to fix it ??
sen="I love dogs"
function Longest_word(sen)
x=" "
maxw=" "
minw=" "
minl=1
maxl=length(sen)
p=0
for i=1:length(sen)
if(sen[i]!=" ")
x=[x[1]...,sen[i]...]
else
p=length(x)
if p<min1
minl=p
minw=x
end
if p>maxl
maxl=p
maxw=x
end
x=" "
end
end
return minw,maxw
end
As #David mentioned, another and may be better solution can be achieved by using split function:
function longest_word(sentence)
sp=split(sentence)
len=map(length,sp)
return (sp[indmin(len)],sp[indmax(len)])
end
The idea of your code is good, but there are a few mistakes.
You can see what's going wrong by debugging a bit. The easiest way to do this is with #show, which prints out the value of variables. When code doesn't work like you expect, this is the first thing to do -- just ask it what it's doing by printing everything out!
E.g. if you put
if(sen[i]!=" ")
x=[x[1]...,sen[i]...]
#show x
and run the function with
Longest_word("I love dogs")
you will see that it is not doing what you want it to do, which (I believe) is add the ith letter to the string x.
Note that the ith letter accessed like sen[i] is a character not a string.
You can try converting it to a string with
string(sen[i])
but this gives a Unicode string, not an ASCII string, in recent versions of Julia.
In fact, it would be better not to iterate over the string using
for i in 1:length(sen)
but iterate over the characters in the string (which will also work if the string is Unicode):
for c in sen
Then you can initialise the string x as
x = UTF8String("")
and update it with
x = string(x, c)
Try out some of these possibilities and see if they help.
Also, you have maxl and minl defined wrong initially -- they should be the other way round. Also, the names of the variables are not very helpful for understanding what should happen. And the strings should be initialised to empty strings, "", not a string with a space, " ".
#daycaster is correct that there seems to be a min1 that should be minl.
However, in fact there is an easier way to solve the problem, using the split function, which divides a string into words.
Let us know if you still have a problem.
Here is a working version following your idea:
function longest_word(sentence)
x = UTF8String("")
maxw = ""
minw = ""
maxl = 0 # counterintuitive! start the "wrong" way round
minl = length(sentence)
for i in 1:length(sentence) # or: for c in sentence
if sentence[i] != ' ' # or: if c != ' '
x = string(x, sentence[i]) # or: x = string(x, c)
else
p = length(x)
if p < minl
minl = p
minw = x
end
if p > maxl
maxl = p
maxw = x
end
x = ""
end
end
return minw, maxw
end
Note that this function does not work if the longest word is at the end of the string. How could you modify it for this case?

String reverse in VB Script without using Built in functions

option explicit
dim r, res, num
num= cint(inputbox("Enter the number"))
do while(num > 0)
r= num mod 10
num= num\10
res= res & r
loop
msgbox res
Well this is the code, now my question is this works perfectly fine for input 1234, well if the input is 0123 it just prints 321 which is wrong.It needs to print 3210.
I am unable to figure out, tried a lot but in vain, any help would be appreciated
Thanks and Regards
You must decide whether you want to reverse strings or numbers (accidentially represented as decimals). If you want to reverse strings, you should
not convert the (string) input to a number/integer
use string ops: Mid() for reading, concatenation & for building
Added: In (demo/not production) code:
Option Explicit
Function rev(s)
Dim p
For p = Len(s) To 1 Step -1
rev = rev & Mid(s, p, 1)
Next
End Function
Dim s
For Each s In Array("1234", "0123")
WScript.Echo s, rev(s)
Next
output:
1234 4321
0123 3210
str = Inputbox("Enter the number")
rev=""
Set regx = New RegExp
regx.Global = True
regx.IgnoreCase = True
regx.Pattern = ".{1}"
Set colchars= regx.Execute(str)
For i = 0 To colchars.Count-1
rev= colchars.Item(i)&rev
Next
MsgBox rev
String reverse program without using Reverse String function & Mid function.
str=inputbox("Enter the string: ")
str1=len(str)
a=Left(str,1)
for i=1 to str1
str2=Left(str,i)
if len(str2)>1 then
str3=Right(str2,1)&temp
temp=str3
end if
next
msgbox temp&a
Try this:
Dim num, rev
num = inputbox("Enter a number")
If Len(num)=4 Then
rev = rev*10 + num mod 10
num = num/10
num = left(num,3)
rev = rev*10 + num mod 10
num = num/10
num = left(num,2)
rev = rev*10 + num mod 10
num = num/10
num = left(num,1)
rev = rev*10 + num mod 10
msgbox "Reverse Order of the number is "&rev
Else
msgbox "Number, you entered is not a 4 digit number"
End If

Split string and replace dot char in Lua

I have a string stored in sqlite database and I've assigned it to a var, e.g. string
string = "First line and string. This should be another string in a new line"
I want to split this string into two separated strings, the dot (.) must be replace with (\n) new line char
At the moment I'm stuck and any help would be great!!
for row in db:nrows("SELECT * FROM contents WHERE section='accounts'") do
tabledata[int] = string.gsub(row.contentName, "%.", "\n")
int = int+1
end
I tried the other questions posted here in stachoverflow but with zero luck
What about this solution:`
s = "First line and string. This should be another string in a new line"
a,b=s:match"([^.]*).(.*)"
print(a)
print(b)
Are you looking to actually split the string into two different string objects? If so maybe this can help. It's a function I wrote to add some additional functionality to the standard string library. You can use it as-is or rename it to what ever you like.
--[[
string.split (s, p)
====================================================================
Splits the string [s] into substrings wherever pattern [p] occurs.
Returns: a table of substrings or, if no match is made [nil].
--]]
string.split = function(s, p)
local temp = {}
local index = 0
local last_index = string.len(s)
while true do
local i, e = string.find(s, p, index)
if i and e then
local next_index = e + 1
local word_bound = i - 1
table.insert(temp, string.sub(s, index, word_bound))
index = next_index
else
if index > 0 and index <= last_index then
table.insert(temp, string.sub(s, index, last_index))
elseif index == 0 then
temp = nil
end
break
end
end
return temp
end
Using it is very simple, it returns a tables of strings.
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> s = "First line and string. This should be another string in a new line"
> t = string.split(s, "%.")
> print(table.concat(t, "\n"))
First line and string
This should be another string in a new line
> print(table.maxn(t))
2

Resources