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...
Hi, Schau Dir mal den Befehl "Lookupstr" an. Wigbert
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! Habe es noch nicht ausprobiert aber würde es in etwa so funktionierten:
1 | dim text as string*10 |
2 | dim char(10) as byte |
3 | dim i as byte |
4 | dim index(10) as byte |
5 | |
6 | text = "ABCDEFGHIJ" |
7 | i = 1 |
8 | |
9 | Do
|
10 | |
11 | 'Einzelne Chars aus String ziehen |
12 | char(i) = mid(text , i , 1) |
13 | |
14 | 'Char in Tabelle data1 suchen und den Index speichern |
15 | index(i) = lookdown(char(i) , data1 , 1) |
16 | |
17 | 'Wert von Index in Tabelle data2 suchen |
18 | char(i) = lookup(index(i) , data2) |
19 | |
20 | loop until i = 10 |
21 | |
22 | printbin char(1) ; char(2) ; char(3) ; ... |
23 | |
24 | |
25 | data1: |
26 | data "A" , "B" , "C" , "D" , "E" , ... |
27 | |
28 | data2: |
29 | data &H00 , &H01 , &H02 , &H03 , ... |
Max
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 ' *** |
13 | Char_val = Char_val - Orig_char_start ' *** |
14 | String_char(char_ctr) = Lookup(char_val , New_char_val) |
15 | Incr Char_ctr |
16 | Char_val = String_char(char_ctr) |
17 | End If ' *** |
18 | Wend |
19 | |
20 | End |
21 | |
22 | New_char_val: |
23 | Data 12 , 22 , 44 , 18 , 5 ' usw. |
Sorry, Fehler bemerkt: Incr Char_ctr muss natürlich unmittelbar nach If/Then stehen, sonst gibt's 'ne Endlosschleife.
Nachtrag, die Zweite:
1 | ... |
2 | End If ' *** |
3 | Incr Char_ctr |
4 | Char_val = String_char(char_ctr) |
5 | Wend |
6 | ... |
Array Indexe beginnen bei Bascom - blöderweise - bei 1. Char_ctr = 0 Char_val = String_char(char_ctr) Gruß Rolf
Find ich auch immer wieder nervig, bei andern Basic-Derivaten kann man es manchmal wenigstens konfigurieren.
@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:
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 = 1 |
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 ' *** |
13 | Char_val = Char_val - Orig_char_start ' *** |
14 | String_char(char_ctr) = Lookup(char_val , New_char_val) |
15 | End If ' *** |
16 | |
17 | Incr Char_ctr |
18 | Char_val = String_char(char_ctr) |
19 | |
20 | Wend
|
21 | |
22 | End
|
23 | |
24 | New_char_val: |
25 | Data 12 , 22 , 44 , 18 , 5 ' usw. |
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.