The Ascw(Char) method returns an Integer value representing the character
code corresponding to a Unicode character. This can be 0 through 65535. The
returned value is independent of the culture and code page settings for the
current thread.
Using a subscript to access the individual characters makes use of the fact
that you can treat a String as if it were an array of Char.
So, the code fragment:
decodeString = String.Empty
For _i = 0 To plainText.Length - 1
If AscW(plainText(_i)) >= 32 AndAlso AscW(plainText(_i)) < 127 Then
decodeString &= plainText(_i)
Next
does nothing more than append all characters from plainText that have their
character codes in the range 32 to 126 inclusive, to decodeString which is,
initially, empty.
Therefore, if you end up with a ? (character code 63) in decodeString, then
it was present in plainText. QED.
If you use another methodology in an attempt to 'remove' non-ASCII and/or
ASCII non-printable characters form a string then you may end up with a
different result, because the culture and/or code page settings for the
current thread may be taken into account.
There is another factor that could come into play here and that is one or
more of the characters in plainText has a character code of 0 (NUL). If you
display such a string with MessageBox.Show, among other methods, then those
characters after the NUL will NOT be displayed.
For example, the string "ABCDE" & ChrW(0) & "?" would be displayed as
the removal of the NUL character having 'exposed' the "?" that you didn't
realise was actually present.
One way of detecting the presence of a NUL character is:
If plainText.Contains(ChrW(0)) Then
' NUL character is present
Else
' NUL character is NOT present
End If
Note that the ChrW(Integer) method is, effectively, the reverse of the
AscW(Char) method in that it returns the character associated with the
specified character code. The character code can be in the range -32768
through 65535 but the values -32768 through -1 are treated the same as
values in the range 32768 through 65535.