Remove Spaces (or other characters) from a String
#1
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
Reply
#2
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$.
Reply
#3
(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. Big Grin

Anyway, I tested it again by putting 4 periods in Test #2 and it still worked! Angel

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
Reply
#4
This is great!!! Was just looking for something like this! Thanks George.
grymmjack (gj!)
GitHubYouTube | Soundcloud | 16colo.rs
Reply
#5
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.  Smile
Reply
#6
(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.  Wink
Reply
#7
(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.  Wink

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
Reply
#8
If it requires a termination character, why not automatically include it on the c side of things?
Reply
#9
(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
Reply
#10
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
Reply




Users browsing this thread: 1 Guest(s)