.NET fixed length strings
Hi all,
I have the following code sample:
Code:
Module Module1
<VBFixedString(8)> Dim strTest As String = ""
Sub Main()
Console.Write(strTest)
End Sub
End Module
I thought this would fix the string to 8 characters regardless of what I set strTest to but its not. So I'm expecting an empty string (like above) to be 8 characters; or if I set strTest to "test" I'm expecting the output to be test with four trailing spaces. Or if I set it greater than 8 characters it should throw an exception.
Am I using the above in the proper context or should I be using something else to achieve fixed length strings?
Thanks,
Strick
Re: .NET fixed length strings
Only certain base classes actually look at that vbfixedstring value to pad/truncate the string value.
you could make it a constant. But the value has to be predefined.
Justin
Re: .NET fixed length strings
Quote:
Originally Posted by
MonkOFox
Only certain base classes actually look at that vbfixedstring value to pad/truncate the string value.
you could make it a constant. But the value has to be predefined.
Justin
So if you wanted to use a fixed length string you'd have to make a class or function and call it on your string everytime you changed it?
Maybe something like... ?....
Code:
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
' fix to 8 char length
Debug.Print(">" & FixStrLength("1234567890", 8) & "<")
' fix to 4 char length
Debug.Print(">" & FixStrLength("123", 4) & "<")
End Sub
Private Function FixStrLength(strIn As String, MaxLength As Integer) As String
If strIn.Length > MaxLength Then ' remove excess chars.
Return strIn.Substring(0, MaxLength)
ElseIf strIn.Length < MaxLength Then 'add needed spaces to fill to length
Return strIn & New String(" "c, MaxLength - strIn.Length)
Else
Return strIn 'nothing to do
End If
End Function
Re: .NET fixed length strings
Hi,
Thanks for your response. Do you know what these "certain base classes" are? I'd have to use these then because unfortunately I can't deviate from these requirements.
Thanks,
Strick
Re: .NET fixed length strings
Quote:
Originally Posted by
Edgemeal
So if you wanted to use a fixed length string you'd have to make a class or function and call it on your string everytime you changed it?
Maybe something like... ?....
Code:
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
' fix to 8 char length
Debug.Print(">" & FixStrLength("1234567890", 8) & "<")
' fix to 4 char length
Debug.Print(">" & FixStrLength("123", 4) & "<")
End Sub
Private Function FixStrLength(strIn As String, MaxLength As Integer) As String
If strIn.Length > MaxLength Then ' remove excess chars.
Return strIn.Substring(0, MaxLength)
ElseIf strIn.Length < MaxLength Then 'add needed spaces to fill to length
Return strIn & New String(" "c, MaxLength - strIn.Length)
Else
Return strIn 'nothing to do
End If
End Function
Hi Edgemeal,
Yeah I thought about writing my own class to do this, but I just figured something like this is common and built into the .net framework.
Thanks,
Strick
Re: .NET fixed length strings
Depending on the version of .NET, couldn't you use the String.PadLeft or String.PadRight methods on the return value?
http://msdn.microsoft.com/en-us/library/34d75d7s.aspx
So you would return
Code:
Console.Write(strTest.PadRight(8))
This is available in .NET 2.0 and later.
You could also use this version of PadRight: http://msdn.microsoft.com/en-us/library/36f2hz3a.aspx which will allow you to specify what Chr code to use for the padding character.
If you wanted to limit the string to no more than 8 characters, you could return:
Console.Write(strTest.PadRight(8).Remove(9))
http://msdn.microsoft.com/en-us/library/9ad138yc.aspx
Which would return only the FIRST 8 characters, or you could use Strings.Right(...) to return only the left most characters...
This would ensure your function always outputs 8 characters, but there would be no constraint on the return value that would prevent other functions from changing the length of the string.
For this you would probably need to create a custom class to enforce the constraint in a Property value, which wouldn't be terribly difficult.
Re: .NET fixed length strings
You guys do realize that you can create a "fixed length" string containing the 8 spaces by doing:
Code:
<VBFixedString(8)> Dim strTest As New String(" ", 8I)
And as for keeping it fixed length, you can create a property that'll handle keeping that string fixed length:
Code:
Private Property Test() As String
Get
Return strTest
End Get
Set (ByVal value As String)
If value.Length > 8I Then
strTest = value.SubString(0I, 8I)
Else
strTest = String.PadRight(value, 8I)
End If
End Set
End Property
Re: .NET fixed length strings
Quote:
Originally Posted by
stricknyn
Hi all,
I have the following code sample:
Code:
Module Module1
<VBFixedString(8)> Dim strTest As String = ""
Sub Main()
Console.Write(strTest)
End Sub
End Module
I thought this would fix the string to 8 characters regardless of what I set strTest to but its not. So I'm expecting an empty string (like above) to be 8 characters; or if I set strTest to "test" I'm expecting the output to be test with four trailing spaces. Or if I set it greater than 8 characters it should throw an exception.
Am I using the above in the proper context or should I be using something else to achieve fixed length strings?
Thanks,
Strick
Is this related to some VisualBasicIO file format?
Re: .NET fixed length strings
The question is why. Aside from some API calls that require fixed length strings as parameters I don't imagine any other situation where you might need them. If you need a fixed length string field for an API call you should use MarshalAs attribute, for example this snippet declares a string with the length fixed at 32 characters:
vb Code:
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> _
Public lfFaceName As String
There IS a difference between a fixed length string and a string whose length is limited by the program code. The original poster's problem is best solved by the use of formatting:
vb Code:
Dim value As String = "test"
Debug.Print(String.Format("|{0,-20}|", value)) ' Right aligned 20 characters field
Debug.Print(String.Format("|{0,20}|", value)) ' Left aligned 20 characters field
More information here:
Composite formatting
Re: .NET fixed length strings
Do you want to consider using Character array instead?
Re: .NET fixed length strings
your soul can be redemed with this code:
Code:
Dim S(8) As Char
S = "01234567".ToCharArray
and I'll tell you a secret as well.
A string is a byte array as well. For each character two bytes are used (unicode).
Sometimes it's usefull to ignore the second byte to do stuff like compression.
You need to be sure the text is ASCII code so the second byte is a zero.
Have Fun!
Re: .NET fixed length strings
I agree with cicatrix; I think the right response to your question is another question: why does it matter? Generally you only bother with fixed-width strings when dealing with a particularly picky API through COM interop or P/Invoke.
Basically, what the attribute does is give a hint to the compiler about what should happen if you give the string to COM or P/Invoke. It's still a normal .NET string and you're free to make it smaller or larger than 8 bytes. The magic happens when you make an API call; instead of doing the normal translation, the compiler makes sure to allocate exactly 8 bytes and fill those 8 bytes as best as it can. When it's a value in a Structure or passed by reference the end result is the unmanaged code feels like it's getting a pointer to 8 bytes; if you don't use the attribute it gets a pointer to however many bytes the string uses.
It is usually rare that you need this attribute; if you can explain why you think you need it we might be able to save you some trouble.
If your problem is you want a string that is always padded to 8 characters, cicatrix's String.Format() examples present the most simple solution.
Re: .NET fixed length strings
A benchmark is useless without the code that performs it. You could be committing some error that makes it appear that Format() is slower than it is. (Though considering the complexity of "pad" vs. "handle many formatting scenarios" I don't doubt Format() is slower.)
However, you should also consider the magnitude of your results. Sure, String.Format() took 4 times as long to pad 10,000 strings, but could you notice a visible difference? 3ms passes by before you can blink your eyes. If we decide to extrapolate from the results that Format() takes 0.00273ms per operation, we can discover that you can pad 366,300 strings before it starts to take 1s. That's a lot. Sure, you could do at least a million in that second using PadRight(), but I struggle to come up with a case where I need to get a million strings ready in a hurry.
I'm not saying PadRight() is wrong; in this case it may be a more logical choice. But the benchmark numbers posted so far don't make me afraid of using Format either. I only optimize for performance when I know there's a problem.
It may even be irrelevant; the OP hasn't revealed what behavior they really want, so we could be bickering over which wrong solution is the fastest.