 |
 |

12-29-2009, 07:42 PM
|
 |
Junior Contributor
|
|
Join Date: Jul 2002
Location: California
Posts: 240
|
|
Help in understanding this "Mid" statement
|
Well I'm back in the land of CrystalPoint's "CommBASIC" again. They say this "Mid" statement will replace characters in a string with characters you specify, only I'm having trouble udnerstanding it (ultimately I want to remove commas from text lines I'm reading into an array).
In the documamentation:
Replaces part (or all) of one string with another string, starting at a specified location.
Syntax Mid ( stringvar$, start%[, length%] ) = string$
where: is:
stringvar$ The string to change.
start% An expression for the position to begin replacing characters.
length% An expression for the number of characters to replace.
string$ The string to place into another string.
!stuff omitted by Sidewinder!
Mid never changes the number of characters in stringvar$.
!more omission!
The index of the first character in a string is 1.
The only arguments it accepts are the starting $stringvar, the integer start position, and the optional length - nowhere is it accepting as an argument what character I want to put in there as a replacement?
They offer this example:
Code:
Sub main
Dim username as String
Dim position as Integer
Dim count as Integer
Dim uname as String
Dim replacement as String
username=InputBox("Enter your full name:")
uname=username
replacement="*"
Do
position=InStr(username," ")
If position=0 then
Exit Do
End If
username=Mid(username,position+1)
count=count+position
Loop
For x=1 to Len(username)
count=count+1
Mid(uname,count)=replacement
Next x
MsgBox "Your name now is: " & uname
End Sub
Which I tried, and it worked - replacing my surname with asterisks.
Questions:
1. How are we getting out of that Do Loop? InStr returns the position within the string (referenced by the 1st argument) of the string ref'd by the 2nd. It returns 0 if the 2nd string isn't found. There's no other way to get out of the Do Loop if InStr didn't return 0, right?
2. What is happening to the variable username in the line "username=Mid(username,position+1)" ? As I asked about above, "Mid" doesn't ask what you want the new character to be, so how is the string being changed?
3. Basically the same question as 2, but about the line "Mid(uname,count)=replacement" ?? What's going on here?
Thanks in advance.
|
|

12-29-2009, 10:55 PM
|
 |
Hydrogen Powered
Administrator * Expert *
|
|
Join Date: Jul 2003
Location: Sacramento, CA
Posts: 6,090
|
|
Mid() is a sneaky function, and if I recall correctly, the usage you ask about in question 3 is hard to find in the documentation.
The usual use of Mid() is to extract a substring from a string - you specify the original string {stringvar}, a starting position {start} and OPTIONALLY how many characters you want [length]. If you do NOT specify the length then Mid() returns all the characters from the original string starting at the position specified by {start}.
The special use of Mid() where it appears to the LEFT of the equals sign is to replace a SINGLE character with another character. You could think of this as being:
Mid (stringvar, position) = newchar -- where newchar is a single character string and position must be in the range of 1 to Len(stringvar).
While there are better ways to accomplish it, the Do..Loop is looking for 'last' piece of the string you entered using SPACE as the delimiter - InStrRev() could get you this position in one function call. You will exit the Do Loop when count is pointing to the position of the last space in the string you entered for username (this is when InStr() returns 0 because there are no more spaces.
EDIT: I remembered why you don't easily find the second version of Mid() in the documentation - it is no longer a FUNCTION it is a STATEMENT - here is the more complete MSDN entry on that version: http://msdn.microsoft.com/en-us/libr...66(VS.60).aspx - I haven't used it in so long I forgot that you can replace more than one character if you specify a length (though you cannot change the length of the string you are putting replacement characters into).
|
__________________
"With the appearance of the AddressOf operator, an entire industry has developed among authors illustrating how to do previously impossible tasks using Visual Basic. Another industry is rapidly developing among consultants helping users who have gotten into trouble attempting these tasks." -Dan Appleman
|

12-30-2009, 12:28 PM
|
 |
Junior Contributor
|
|
Join Date: Jul 2002
Location: California
Posts: 240
|
|
Thanks webbone!
Please bear with me while I struggle toward understanding this (I am still pretty new to this whole programming racket!)
Do
position=InStr(username," ")
If position=0 then
Exit Do
End If
username=Mid(username,position+1)
'Here, we are replacing the previous value of username with just the last name (after the space (since the space is position) to the whole end of the string; 'cause that's the default when the Mid() doesn't get a length argument.)
count=count+position
'Here... I don't get it. Since count was never initialized, its value is zero, right? Why not just count=position ?
Loop
'As we loop, username has a new value, one free of spaces (a risky assumption; since some people are named Van Pelt or De Los Reyes!); therefore re-evaluating the exact same variable now satisfies the condition to exit the loop? (I don't buy that this is a best-practice way of doing this; a)it assumes a no-spaces surname and b)it's not the most scrutable code structure, from where I sit!!)
count=count+1
'This is the character index of the surname in the original value of username, before Mid() modified it! count, at its first appearance, was initialized to the value of position at the top of the Do Loop, and never modified after that since the Do Loop will have exited before returning to that line where it was initialized.
Mid(uname,count)=replacement
'Easy enough, I guess - this syntax of Mid() causes whichever character whose index position is count within the string uname to be replaced with replacement. (I wonder why they set it to a variable, wouldn't it have worked just as well to use "*" as a string literal? (Is that proper use of the term "string literal?" )
Thanks again for your help!!!
|
Last edited by Sidewinder; 12-30-2009 at 12:35 PM.
|

12-30-2009, 01:34 PM
|
 |
MetaCenturion
Retired Moderator * Guru *
|
|
Join Date: Aug 2001
Location: California, USA
Posts: 16,583
|
|
Quote:
|
'Here, we are replacing the previous value of username with just the last name (after the space (since the space is position) to the whole end of the string; 'cause that's the default when the Mid() doesn't get a length argument.)
|
Yes, but remember that you are in a Do Loop (with crude Exit I might add) so you will be constantly "updating" username with everything after each space that it finds:
For instance:
"James Earl Jones" -> "Earl Jones" after the first loop -> "Jones" after the second loop.
At this point, the loop exits with the last 'name' in the username.
Quote:
|
'Here... I don't get it. Since count was never initialized, its value is zero, right? Why not just count=position ?
|
It is in a loop. The first time the loop runs, count is 0, but after the loop loops, count is nonzero (6 using the "James Earl Jones" note)
Quote:
|
'As we loop, username has a new value, one free of spaces (a risky assumption; since some people are named Van Pelt or De Los Reyes!); therefore re-evaluating the exact same variable now satisfies the condition to exit the loop? (I don't buy that this is a best-practice way of doing this; a)it assumes a no-spaces surname and b)it's not the most scrutable code structure, from where I sit!!)
|
True, but you also have to define exactly what constitutes a last name before you can even begin to programatically write out a way to decipher the surname.
Example with random names strung together (apologize if this is anyone's name): Larry David Joe Stephens ... what's the last name? Stephens? Joe Stephens?
I will however agree that the Exit Do is unsightly when the loop could be written with the condition in the Do. You can move position=InStr(username," ") before the loop with position=InStr(username," ") again at the end of the loop, and remove the If with Exit in it altogether. Now you can have Do Until position = 0 rather than just Do.
Quote:
|
'This is the character index of the surname in the original value of username, before Mid() modified it! count, at its first appearance, was initialized to the value of position at the top of the Do Loop, and never modified after that since the Do Loop will have exited before returning to that line where it was initialized.
|
Correct, except count is initialized to 0 before it entered the Do Loop and has values added to it while it is in the loop.
With the "James Earl Jones" example, count should end up being 12 before calling the final Mid statement.
Quote:
|
'Easy enough, I guess - this syntax of Mid() causes whichever character whose index position is count within the string uname to be replaced with replacement. (I wonder why they set it to a variable, wouldn't it have worked just as well to use "*" as a string literal? (Is that proper use of the term "string literal?" )
|
A good modularity tip of code is not to use "magic values", or hardcoded constants (string literals are how you write strings in code and yes, anything in between " " is a string literal or string constant), but instead either declare Constants or pick up the values from variables.
|
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|
|
|
|
 |
|