Posts: 11
Threads: 3
Joined: Apr 2022
Reputation:
1
12-29-2022, 01:28 AM
(This post was last modified: 12-29-2022, 01:34 AM by George McGinn.)
Awhile back I needed to remove SPACES (and sometimes other characters) from a string in some of my C code.
The need to do so in QB64 reared its ugly head again today, so I resurrected my code and now have incorporated it into any QB64 program I will need it in.
You pass the function 2 parameters - The string you want to change, and the character(s) you want removed. For example, if I want spaces and periods to be removed from a sentence, I pass " ." in the second argument. You don't need to run this function multiple times to accomplish this.
Here is the C/C++ Header file:
Code: (Select All) #include <stdio.h>
/* search for character(s) */
int string_search_chr(char *tokens,char s){
if (!tokens || s=='\0')
return 0;
for (;*tokens; tokens++)
if (*tokens == s)
return 1;
return 0;
}
char *string_remove_chr(char *str,const char *tokens) {
char *src = str , *dst = str;
/* validate input */
if (!(str && tokens))
return NULL;
while(*src)
if(string_search_chr(tokens,*src))
src++;
else
*dst++ = *src++; /* assign first, then incement */
*dst='\0';
return str;
}
Here is the QB64 program that tests the above:
Code: (Select All) DECLARE LIBRARY "./removeStr"
FUNCTION __REMOVESPACES$ ALIAS string_remove_chr(qString$, charValue$)
END DECLARE
QBMain:
PRINT "QB64: Test #1 - Remove SPACES from 'New York Yankees"
qString$ = "New York Yankees"
retValue$ = __REMOVESPACES$(qString$+CHR$(0), " ")
PRINT "QB64: qString$ = "; qString$
PRINT "QB64: retValue$ = "; retValue$
PRINT
PRINT "QB64: Used in a PRINT stmt, function returns: "; __REMOVESPACES$(qString$+CHR$(0), " ")
PRINT
PRINT "QB64: Test #2 -Remove SPACES and PERIODS from 'New York Yankees."
qString$ = "New York Yankees"
retValue$ = __REMOVESPACES$(qString$+CHR$(0), " .")
PRINT "QB64: qString$ = "; qString$
PRINT "QB64: retValue$ = "; retValue$
PRINT
PRINT "QB64: Used in a PRINT stmt, function returns: "; __REMOVESPACES$(qString$+CHR$(0), " ")
PRINT
SYSTEM 0
This is the output from running the above code:
Quote:QB64: Test #1 - Remove SPACES from 'New York Yankees
QB64: qString$ = New York Yankees
QB64: retValue$ = NewYorkYankees
QB64: Used in a PRINT stmt, function returns: NewYorkYankees
QB64: Test #2 -Remove SPACES and PERIODS from 'New York Yankees.
QB64: qString$ = New York Yankees
QB64: retValue$ = NewYorkYankees
QB64: Used in a PRINT stmt, function returns: NewYorkYankees
------------------
(program exited with code: 0)
Press return to continue
—————————————————————————————
George McGinn
Theoretical/Applied Computer Science Specialist
Member: IEEE, IEEE Computer Society
Technical Council on Software Engineering
IEEE Standards Association
Society of American Baseball Research
Posts: 1,586
Threads: 59
Joined: Jul 2022
Reputation:
52
Hi George.
Useful function, but you forgot in the example, just below the comment for test #2 to include a period as the value of qstring$.
Posts: 11
Threads: 3
Joined: Apr 2022
Reputation:
1
(12-29-2022, 01:36 AM)mnrvovrfc Wrote: Hi George.
Useful function, but you forgot in the example, just below the comment for test #2 to include a period as the value of qstring$.
Good catch! And I thought it worked.
Anyway, I tested it again by putting 4 periods in Test #2 and it still worked!
Here is the test output.
Quote:QB64: Test #1 - Remove SPACES from 'New York Yankees
QB64: qString$ = New York Yankees
QB64: retValue$ = NewYorkYankees
QB64: Used in a PRINT stmt, function returns: NewYorkYankees
QB64: Test #2 -Remove SPACES and PERIODS from 'New York Yankees.
QB64: qString$ = New York.Yankees...
QB64: retValue$ = NewYorkYankees
QB64: Used in a PRINT stmt, function returns: NewYork.Yankees...
------------------
(program exited with code: 0)
Press return to continue
—————————————————————————————
George McGinn
Theoretical/Applied Computer Science Specialist
Member: IEEE, IEEE Computer Society
Technical Council on Software Engineering
IEEE Standards Association
Society of American Baseball Research
Posts: 476
Threads: 25
Joined: Nov 2022
Reputation:
45
This is great!!! Was just looking for something like this! Thanks George.
Posts: 2,698
Threads: 327
Joined: Apr 2022
Reputation:
217
12-29-2022, 04:09 AM
(This post was last modified: 12-29-2022, 08:33 AM by SMcNeill.)
I just did one of these the other day, and it's in my BadLimits post:
Code: (Select All) Function RemoveCharacters$ (passed_from_what As String, what_character As String, from_which_side As Integer)
'from_which_side: 1 = left, 2 = right, 3 = left and right, 0 = whole string
Dim from_what As String
from_what = passed_from_what
If from_which_side = 0 Then 'strip from the whole string
Do
p = InStr(from_what, what_character)
If p Then from_what = Left$(from_what, p - 1) + Mid$(from_what, p + 1)
Loop Until p = 0
End If
If from_which_side And 1 Then 'strip from the left
Do Until Left$(from_what, 1) <> what_character
from_what = Mid$(from_what, 2)
Loop
End If
If from_which_side And 2 Then 'strip from the right
Do Until Right$(from_what, 1) <> what_character
from_what = Left$(from_what, Len(from_what) - 1)
Loop
End If
RemoveCharacters = from_what
End Function
Use the above function to remove from left side, right side, or the whole string, whatever characters you want removed.
Posts: 2,698
Threads: 327
Joined: Apr 2022
Reputation:
217
(12-29-2022, 01:28 AM)George McGinn Wrote: Awhile back I needed to remove SPACES (and sometimes other characters) from a string in some of my C code.
The need to do so in QB64 reared its ugly head again today, so I resurrected my code and now have incorporated it into any QB64 program I will need it in.
You pass the function 2 parameters - The string you want to change, and the character(s) you want removed. For example, if I want spaces and periods to be removed from a sentence, I pass " ." in the second argument. You don't need to run this function multiple times to accomplish this.
Here is the C/C++ Header file:
Code: (Select All) #include <stdio.h>
/* search for character(s) */
int string_search_chr(char *tokens,char s){
if (!tokens || s=='\0')
return 0;
for (;*tokens; tokens++)
if (*tokens == s)
return 1;
return 0;
}
char *string_remove_chr(char *str,const char *tokens) {
char *src = str , *dst = str;
/* validate input */
if (!(str && tokens))
return NULL;
while(*src)
if(string_search_chr(tokens,*src))
src++;
else
*dst++ = *src++; /* assign first, then incement */
*dst='\0';
return str;
}
Here is the QB64 program that tests the above:
Code: (Select All) DECLARE LIBRARY "./removeStr"
FUNCTION __REMOVESPACES$ ALIAS string_remove_chr(qString$, charValue$)
END DECLARE
QBMain:
PRINT "QB64: Test #1 - Remove SPACES from 'New York Yankees"
qString$ = "New York Yankees"
retValue$ = __REMOVESPACES$(qString$+CHR$(0), " ")
PRINT "QB64: qString$ = "; qString$
PRINT "QB64: retValue$ = "; retValue$
PRINT
PRINT "QB64: Used in a PRINT stmt, function returns: "; __REMOVESPACES$(qString$+CHR$(0), " ")
PRINT
PRINT "QB64: Test #2 -Remove SPACES and PERIODS from 'New York Yankees."
qString$ = "New York Yankees"
retValue$ = __REMOVESPACES$(qString$+CHR$(0), " .")
PRINT "QB64: qString$ = "; qString$
PRINT "QB64: retValue$ = "; retValue$
PRINT
PRINT "QB64: Used in a PRINT stmt, function returns: "; __REMOVESPACES$(qString$+CHR$(0), " ")
PRINT
SYSTEM 0
This is the output from running the above code:
Quote:QB64: Test #1 - Remove SPACES from 'New York Yankees
QB64: qString$ = New York Yankees
QB64: retValue$ = NewYorkYankees
QB64: Used in a PRINT stmt, function returns: NewYorkYankees
QB64: Test #2 -Remove SPACES and PERIODS from 'New York Yankees.
QB64: qString$ = New York Yankees
QB64: retValue$ = NewYorkYankees
QB64: Used in a PRINT stmt, function returns: NewYorkYankees
------------------
(program exited with code: 0)
Press return to continue
There's a couple of small glitches in this, that you might want to take a look at and fix, @ George McGinn.
First, there's the whole need to set the compiler to allow -fpermissive so this will run. Types don't match properly, so you might want to tweak them a little.
Second is this alters the original string, corrupting it, as shown below:
Code: (Select All) Declare CustomType Library "removeStr"
Function __REMOVESPACES$ Alias string_remove_chr (qString$, charValue$)
End Declare
check$ = "This is a string that we're going to check to see how long it would take to remove the spaces from."
Print check$
Print "The length of our test string is:"; Len(check$)
new$ = __REMOVESPACES$(check$, " ")
Print check$, Len(check$)
End
check$ remains the same length as previously, but the left side of it now mirrors new$. You might want to assign your string to a temp string and process it, rather than process the original as you go along, to preserve it.
Posts: 11
Threads: 3
Joined: Apr 2022
Reputation:
1
(12-29-2022, 08:30 AM)SMcNeill Wrote: There's a couple of small glitches in this, that you might want to take a look at and fix, @George McGinn.
First, there's the whole need to set the compiler to allow -fpermissive so this will run. Types don't match properly, so you might want to tweak them a little.
Second is this alters the original string, corrupting it, as shown below:
Code: (Select All) Declare CustomType Library "removeStr"
Function __REMOVESPACES$ Alias string_remove_chr (qString$, charValue$)
End Declare
check$ = "This is a string that we're going to check to see how long it would take to remove the spaces from."
Print check$
Print "The length of our test string is:"; Len(check$)
new$ = __REMOVESPACES$(check$, " ")
Print check$, Len(check$)
End
check$ remains the same length as previously, but the left side of it now mirrors new$. You might want to assign your string to a temp string and process it, rather than process the original as you go along, to preserve it.
The reqason your value is corrupted is because you need to terminate a variable with CHR$(0). Line new$ = __REMOVESPACES$(check$, " ") needs to be new$ = __REMOVESPACES$(check$+CHR$(0), " ") - It seems that when you pass variables, you need to tell it when it ends. Literals do not have that problem.
Without a NULL terminator, C does not know when your variable ends. So it keeps going.
If you want to, you could leave your code as-is, but do this:
Code: (Select All) check$ = "This is a string that we're going to check to see how long it would take to remove the spaces from." + CHR$(0)
However, doing the above messes up the QB64 PRINT statement results.
—————————————————————————————
George McGinn
Theoretical/Applied Computer Science Specialist
Member: IEEE, IEEE Computer Society
Technical Council on Software Engineering
IEEE Standards Association
Society of American Baseball Research
Posts: 2,698
Threads: 327
Joined: Apr 2022
Reputation:
217
If it requires a termination character, why not automatically include it on the c side of things?
Posts: 11
Threads: 3
Joined: Apr 2022
Reputation:
1
12-29-2022, 02:56 PM
(This post was last modified: 12-29-2022, 02:58 PM by George McGinn.)
(12-29-2022, 02:25 PM)SMcNeill Wrote: If it requires a termination character, why not automatically include it on the c side of things?
I tried that once. I can't remember the issues I faced, but I think it has to do with how QB64 is passing variables vs literals to the C/C++ function.
In C, when a C program passes a variable to a C function, it is only an issue when constructing using strcpy or strcat statements (or doing malloc).
—————————————————————————————
George McGinn
Theoretical/Applied Computer Science Specialist
Member: IEEE, IEEE Computer Society
Technical Council on Software Engineering
IEEE Standards Association
Society of American Baseball Research
Posts: 128
Threads: 12
Joined: Apr 2022
Reputation:
14
I often end up using custom approaches to this depending on the situation.
When your string is very long (>1MB) performance very much depends on how you build up the new string.
- You can walk over the input-string and per character decide if you add it to the result-string
- Per character to remove, you can search (instr) and replace in a loop
- You can use _memcopy to copy all parts between characters you want to remove
- Or if possible the best: Use the original string in your processing and skip characters not wanted. This prevents in memory copying.
45y and 2M lines of MBASIC>BASICA>QBASIC>QBX>QB64 experience
|