Forum: PC-Programmierung [vb.net] Wie Sonderzeichen zu Bytes konvertieren?


von Int32 (Gast)


Lesenswert?

Hallöchen,

ich lese von einem seriellen Port die Daten ein, ein Großteil soll 
einfach in eine RichTextBox geschrieben werden, mit Regex habe ich diese 
Daten entsprechend gruppiert bzw. lasse sie in die Box schreiben.

Ich lese erstmal alles von ReadExisting in einen String.

Jetzt gibt es aber auch noch Daten, die ich als Hex Bytes brauche, und 
die sich als Text nicht darstellen lassen (Sonderzeichen wie ¢ (a2 als 
Hex) oder Þ (DE als Hex). Ich sammle die Daten per Regex auf (matche 
alles Zwischen Begin-of-Line und End-of-line) und speichere sie in eine 
Variable (as Char), ich denke das Problem liegt hier!?

Aussehen soll das am Ende so: AA (Start of text) A2 20 DE FF (End of 
text), da will ich auslesen was als zweites Byte eingelesen wird, in 
diesem Fall a2. Die A2 und DE würden "ungültige Konvertierung in der 
Zeichenfolge" bringen, wenn ich sie in eine "as Byte" Variable einlese.

Ich will sie später als Line haben und auslesen was z.B. das dritte 
Zeichen im Hex Format ist.

die Variable "as byte" funktioniert wie gesagt nicht, da "ungültige 
Konvertierung in der Zeichenfolge".

Daher also as char...wollte ich dann zu Bytes konvertieren:
1
Dim charvariable As Char 
2
Dim byteausgabe As Byte = Convert.ToByte(charvariable)

Fehler kommen keine, aber zu funktionieren scheint es nicht:
Ein abschließendes
1
If byteausgabe > 0 Then MsgBox("123")
als Test bleibt ohne Reaktion.

Das Encoding des SerialPort steht auf ISO-8859-1 weil das für die 
RichTextBox mit den Umlauten funktioniert.

Ist mein Ansatz so umsetzbar, oder müsste ich vom SerialPort erstmal 
alles als Byte einlesen? Dann aber zwischenspeichern und die Daten für 
die RichTextBox wieder in String umwandeln? Oder liegt mein Fehler beim 
konvertieren von Char -> Byte?

Vielen Dank

von Schlaumaier (Gast)


Lesenswert?

Einfache Lösung.

Was nicht passt wird passend gemacht. ;)

Also einfach den "Input" in einen String konvertieren.

Danach mit der Replace-Funktion der Reihe nach alle "nicht lesebaren 
Zeichen" in ein Lesbares Zeichen umwandeln.

https://docs.microsoft.com/de-de/dotnet/api/microsoft.visualbasic.strings.replace?view=net-6.0

Bitte beachte aber die Compare-Methode. Ich empfehle dringend Binary. 
Kannst aber auch die andere Methode ausprobieren.


dim tx, eingabe as string
tx = replace (eingabe, chr(32), "/return", Binary) ' dieser Befehl 
ändert ein Return-Code in den Text "/return".

Da ALLE Zeichen vor inkl. Acsii-Code 32 und viele Zeichen hinter ca. 
ascii-Code 200 (je nach gülitgen Zeichensatz) zu nicht erkennbaren 
Zeichen führen, ist das die einzige Methode ein Text "lesbar" zu machen.

Ich setze das sehr oft ein, wenn ich ein Zeichen-Code-Mischmasch 
auflösen muss. Und wenn ich das deutsche Punkt-Komma-Problem lösen musst 
;)


Was dein Besonderen Fall angeht. Ich würde die Routine anwenden bevor 
ich den String an die Rich-Text-Box übergebe.

Und achte auf die Logische Reihenfolge. Notfalls musst du mit einen 
Trick-Zeichen arbeiten. Also ein Zwischen-Replace = umwandeln in "@@@@" 
und dann wieder das Zeichen zurück wenn die restliche Umwandlung 
stattgefunden hat.
Kommt aber sehr selten vor, und ist ein reines Logisches Problem. Da 
Replace ALLES in den String umwandelt.

Grundsätzlich solltest du aber ich mit der CHR-Funktion 
auseinandersetzen.

https://docs.microsoft.com/de-de/dotnet/api/microsoft.visualbasic.strings.chr?view=net-6.0#microsoft-visualbasic-strings-chr(system-int32)

Wenn du das nämlich Zeichenweise machst, und nur bestimmte zeichen 
ändern willst geht auch das.

Dim Eingabe as String = " "  '<- leerzeichen
dim ges_eingabe as string
if Eingabe = chr(13) then eingabe = "leerzeichen"

ges_eingabe = ges_eingabe + eingabe


Viel Glück

ps: Die Links haben zwar visualbasic im Text aber sie zeigen auch den C 
Code an.

Ist nämlich von Feinheiten abgesehen das selbe, da Programmiergrundlagen

von Bartosz B. (bartosz)


Lesenswert?

Schlaumaier schrieb:
> Und wenn ich das deutsche Punkt-Komma-Problem lösen muss

Es geht auch sowas (ausführlich geschrieben):
1
Public Class Form1
2
    Private ReadOnly Deu As New System.Globalization.CultureInfo("de-DE")
3
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
4
        Dim Number As Double = 3.14
5
        Dim converted_to_string As String = Number.ToString(Deu)
6
        TextBox1.Text = converted_to_string
7
    End Sub
8
End Class

======================

@Int32 Ich habe mich selbst mal dran versucht. Ich kenne mich mit den 
Encoding-Geschichten nicht soo gut aus. Vielleicht bekommt man die 
For-Schleife, um an das Encoding zu kommen, noch weg!
1
Public Class Form1
2
    
3
    
4
5
    Private Sub Button2_Click(sender As Object, a As EventArgs) Handles Button2.Click
6
        Dim Test As String = "AA A2 20 DE FF"
7
        Dim split As String() = Test.Split(" "c)
8
9
        Dim EI0 As System.Text.EncodingInfo
10
11
        For Each ei As System.Text.EncodingInfo In System.Text.Encoding.GetEncodings()
12
            If ei.Name = "iso-8859-1" Then
13
                EI0 = ei
14
                Exit For
15
            Else
16
                Continue For
17
            End If
18
        Next
19
20
        If EI0 Is Nothing Then Return
21
22
        Dim enc As System.Text.Encoding = EI0.GetEncoding()
23
        Dim Ba As Byte() = New Byte(split.Length - 3) {}
24
        For i As Integer = 1 To split.Length - 2 Step 1
25
            Ba(i - 1) = hex_to_dec(split(i))
26
        Next
27
        Dim decodedString As String = enc.GetString(Ba)
28
        Debug.WriteLine(decodedString)
29
    End Sub
30
31
    Private Function hex_to_dec(hexnumber As String) As Byte
32
        Dim Value As Byte = 0
33
        Dim ca As Char() = hexnumber.ToCharArray()
34
        Dim value2 As Byte
35
        For i As Integer = ca.Length - 1 To 0 Step -1
36
            Select Case ca(i)
37
                Case "0"c
38
                    value2 = 0
39
                Case "1"c
40
                    value2 = 1
41
                Case "2"c
42
                    value2 = 2
43
                Case "3"c
44
                    value2 = 3
45
                Case "4"c
46
                    value2 = 4
47
                Case "5"c
48
                    value2 = 5
49
                Case "6"c
50
                    value2 = 6
51
                Case "7"c
52
                    value2 = 7
53
                Case "8"c
54
                    value2 = 8
55
                Case "9"c
56
                    value2 = 9
57
                Case "A"c
58
                    value2 = 10
59
                Case "B"c
60
                    value2 = 11
61
                Case "C"c
62
                    value2 = 12
63
                Case "D"c
64
                    value2 = 13
65
                Case "E"c
66
                    value2 = 14
67
                Case "F"c
68
                    value2 = 15
69
                Case Else
70
                    Exit Select
71
            End Select
72
            Value += value2 * CByte(Math.Pow(16, ca.Length - 1 - i))
73
        Next
74
        Return Value
75
    End Function
76
End Class

ergibt ¢ Þ

von Int32 (Gast)


Lesenswert?

Tag nochmal ;)

Die Lösung war am Ende ganz einfach:
1
Dim array As Byte() = Encoding.GetEncoding("ISO-8859-1").GetBytes(hexString)
2
        txtBytes.Text = BitConverter.ToString(array)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.