Hallo!
Ich habe ein Gerät, das eine eigene ASCII Tabelle verwendet zur
Darstellung von Zeichen auf einem Bildschirm. Z.B. entspricht der
Hexwert 00 dem Buchstaben "A" und nicht wie beim ASCII Zeichensatz dem
Leerzeichen.
Jetzt habe ich einen String in BASCOM der so aussieht:
"TEST12345"
Diesen muss ich zerlegen und dann sollte jedem Char im String der
entsprechende Hexwert der ASCII Tabelle des Gerätes zugewiesen werden.
T -> &H13
E -> &H04
S -> &H12
T -> &H13
Wie kann ich das mit Bascom realisieren?
Danke schonmal für die Antworten.
Max
Max wrote:
>> T -> &H13> E -> &H04> S -> &H12> T -> &H13>> Wie kann ich das mit Bascom realisieren?
Mit einer Tabelle (Array)?
In einer Schleife, die über die Länge des Strings geht (Doku
nachschauen, wie man in BACOM rauskriegt wieviele Zeichen in einem
String enthalten sind): Für jedes Zeichen im String, isolierst du jedes
Zeichen einzeln aus dem Eingabestring (Doku nachschauen, wie man bei
BASCOM an einzelne Zeichen eines Strings rankommt). Jedes Zeichen wird
als Index in die Tabelle genommen (Doku nachschauen, wie man ein Array
dimensioniert und mit Werten füllt) und dort steht der Wert, der
stattdessen zu verwenden ist. Diesen Wert nimmst du und schreibst in
anstelle des ursprünglichen Zeichens in den String (Doku nachschauen,
wie man in BASCOM ein Zeichen eines Strings auf einen bestimmten Wert
setzt)
Summa Summarum: Bis auf den Teil: Du brauchst ein Array als
Codeumsetzer, läuft fast alles auf Dokustudium hinaus. Und die Idee
eines Array als Codeumsetzer, hattest du alleine auch schon :-)
(Im übrigen würde ich mal damit anfangen, die Doku zu studieren, ob es
bestimmte Zeichen gibt, die man in BASCOM nicht in einen String packen
kann. Wäre nämlich blöd, wenn sich hinterher dann rausstellt, dass das
so gar nicht funktionieren kann, weil deine Umsetztabelle zu einem
ungültigen Ergebnisstring führen wird.)
Wenn die Zeichen in deinem selber kreierten Zeichensatz die selbe
Reihenfolge haben, wie die Zeichen im ASCII, dann lässt sich deine
Codewandlung durch eine Subtraktion erledigen.
@Ralf
Die Reihenfolge ist leider nicht gleich der im ASCII Zeichensatz. Sonst
wäre es ja auch zu einfach :-)
@Karl Heinz
Wie ich die Stinglänge rausbekomm weiß ich. Wie ich die einzelnen
Zeichen aus dem String bekomme weiß ich auch. Aber den Rest hab ich
nicht verstanden.
Was meinst du mit "Schleife die über die Stinglänge geht" ? Wenn ich die
einzelnen Zeichen habe, wie sage ich BASCOM das aus A ein &H00 werden
soll?
Danke!
Max
Kann Bascom Arrays mit Key => Value-Paaren? Wenn ja einfach eine
entsprechende Tabelle anlegen, vll auch in einem Data-Bereich um ein
wenig Ram zu sparen...
Max wrote:
> Hexwert 00 dem Buchstaben "A" und nicht wie beim ASCII Zeichensatz dem> Leerzeichen.
Na, ja.
Das Leerzeichen hat zwar im ASCII Code einen ganz anderen Wert, aber
seis drum.
Dein Problem besteht darin, dass BASCOM anscheinend, ähnlich wie C,
seine Strings mit 0 abschliesst.
Und da dein Gerät bei einem 'A' den Code 0 sehen will, ist damit das
ganze Konzept des 'einen String in einen anders codierten String zu
verwandeln' schon mal den Bach runter.
Da wird dir nichts anderes übrig bleiben, als die Codeumsetzung direkt
bei der Ausgabe an das Gerät zu machen. Das erscheint mir jetzt
einfacher, als dich in eine 'Na dann wirds wohl nichts mit Strings, da
müssen dann Arrays als Stringersatz herhalten'-Strategie zu jagen.
Karl heinz Buchegger wrote:
> Da wird dir nichts anderes übrig bleiben, als die Codeumsetzung direkt> bei der Ausgabe an das Gerät zu machen. Das erscheint mir jetzt> einfacher, als dich in eine 'Na dann wirds wohl nichts mit Strings, da> müssen dann Arrays als Stringersatz herhalten'-Strategie zu jagen.
Niemand will hier Strings durch Arrays ersetzen. Er will ein Mapping
zwischen einem Zahlenwert und einem Buchstaben herstellen, das macht man
nunmal über eine Tabelle, in fachkreisen dann auch Array genannt.
Dominique Görsch wrote:
> Karl heinz Buchegger wrote:>> Da wird dir nichts anderes übrig bleiben, als die Codeumsetzung direkt>> bei der Ausgabe an das Gerät zu machen. Das erscheint mir jetzt>> einfacher, als dich in eine 'Na dann wirds wohl nichts mit Strings, da>> müssen dann Arrays als Stringersatz herhalten'-Strategie zu jagen.>> Niemand will hier Strings durch Arrays ersetzen. Er will ein Mapping> zwischen einem Zahlenwert und einem Buchstaben herstellen, das macht man> nunmal über eine Tabelle, in fachkreisen dann auch Array genannt.
Yep. Und blöderweise ist sein Mapping so, dass er das Ergebnis dieser
Umsetzung in einem BASCOM String nicht mehr speichern kann, damit er es
dann seiner vorgefertigten (UART)-Schreibfunktion übergeben kann, die
den so umgemappten String zum Gerät überträgt.
Hallo,
ich empfehle die karo einfach Methode.
Den String zeichen für Zeichen auslesen.
Dann einfach in einer CASE Anweisung das Mapping von Istzeichen zu
Sollzeichen durchführen und diese dann einfach seriell ausgeben.
Brühwarm ins Senderegister kopieren.
Das ist trivial und rasend schnell.
Natürlich mußt du noch ein wenig Logik reinbringen was Stringende etc.
betrifft.
Das ist aber sehr einfach, keine Interrupts, DO Loop und fertig.
Ohne es getestet zu haben, aber aus dem Bauch heraus bezweifel ich, dass
Schleife und Lookup langsamer sind als ein CASE. Denn Case wird doch im
Endeffekt auch nur in haufenweise Verschachtelte If's aufgelöst und wenn
du z.B. nach dem letzten Zeichen suchst, durchläufst du jede einzelne
Entscheidung...
Das obige Beispiel ist schon nicht schlecht, allerdings braucht man
"index" nicht als Array, da dort immer nur ein Wert beim
Schleifendurchlauf zwischengespeichert wird. Was oben noch fehlt ist
eine Logik zur Erkennung des Stringende, damit man nicht auf feste
Längen angewiesen ist.
Warum einfach, wenn's auch kompliziert geht ;-)
Untenstehender Code sollte das Gewünschte wirtschaftlich und schnell
erledigen, allerdings nicht getestet.
Damit würde man z.B. nur Buchstaben umzuwandeln. Man könnte auch den
kompletten alten Zeichensatz übersetzen, muss dann aber auch eine
vollständige Lookuptabelle mit allen 256 Einträgen erzeugen. Für diesen
Fall die mit Sternchen bezeichneten Codeteile weglassen.
1
Const Strl = 20 ' Länge des Strings
2
Const Orig_char_start = 64 ' Dezimalwert bei dem die alten Zeichen beginnen
3
Const Orig_char_end = 91 ' Dezimalwert bei dem die alten Zeichen enden
4
Dim String_in As String * Strl
5
Dim String_char(strl) As Byte At String_in Overlay
6
Dim Char_ctr As Byte , Char_val As Byte
7
8
Char_ctr = 0
9
Char_val = String_char(char_ctr)
10
11
While Char_val > 0
12
If Char_val >= Orig_char_start And Char_val <= Orig_char_end Then ' ***
@gast:
Ja, Danke, Du hast recht, hatte ich einen Moment nicht dran gedacht.
Würde ja für den OP viel zu leicht, wenn man wirklich fehlerfreien Code
liefern würde. :D
Problem ist einfach zu lösen, indem statt mit 0:
Char_ctr = 1
initiert wird, weitere Änderungen sind nicht notwendig.
@MWS
Vielen Dank für deinen Code. Ich habe ihn getestet und soweit
funktioniert er auch, allerdings komme ich mit der lookup tabelle nicht
ganz klar.
Hier nochmal der Code:
string_in ="AAAAAAAAAABBBBBBBBBB"
Ich habe testweise den Wert von char_val mit print char_val am UART
ausgegeben und es erscheinen auch die Dezimalwerte 65 und 66 (jeweils
10x).
Wie löse ich das mit der lookup tabelle?
Ich bekomme ja für ein "A" als char_val 65. Muss ich die Tabelle jetzt
mit mindestens 65 Werten füllen, damit per lookup der Wert für "A"
gefunden wird.
Vielleicht kannst Du mir nochmal ein kurzes Beispiel geben.
Folgende Hexwerte sollen den Chars entsprechen
A = &H00
B = &H01
C = &H02
...
1 = &H1E
2 = &H1F
3 = &H20
...
Danke schonmal.
Max wrote:
>Ich bekomme ja für ein "A" als char_val 65. Muss ich die Tabelle jetzt>mit mindestens 65 Werten füllen, damit per lookup der Wert für "A">gefunden wird.
Kommt drauf an, welche Zeichen du alle darstellen willst.
Großbuchstaben gehen von dezimal 65 - 90, Zahlen von 48-57.
Wenn das alles ist und du es so machen willst wie oben beschrieben,
fängst du in deinem Data mit dem char_val des kleinsten Wertes an, also
mit der 0.
Dieses hat dann den Index 0, also musst du immer 48 vom Byte-Wert des
Zeichens abziehen.
Dazu hat MWS das hier eingefügt:
1
Char_val = Char_val - Orig_char_start ' ***
wobei du
Const Orig_char_start = 64 abändern musst in
Const Orig_char_start = 65
weil Lookup widerum bei 0 anfängt
Wenn du sonst keine anderen Zeichen darstellen willst, kannst du auf das
ganze Lookup und Data Zeugs verzichten und schreibst einfach:
Char_ctr = 1
While String_char(char_ctr) > 0
If String_char(char_ctr) > 64 Then ' ***
Char_val = Char_val - 65 ' für die Großbuchstaben
else
Char_val = Char_val - 48 'für die Zahlen
End If ' ***
Printbin char_val;
Incr Char_ctr
Wend
Gruß
Martha