BlackJack hat geschrieben:@Bitfish: Wieso an Zweigergruppen? Oder müssen die Sternchen immer an geraden Indexen beginnen?
Naja, Ich dachte es wäre einfacher, den string in zweiergruppen zu zerlegen, und in einer for-schleife gegen das special_chars dict zu prüfen.
Ich würde das mit einem regulären Ausdruck machen.
Warum?
Mit der von User:martin101986 genannten lösung kann ich vollkommen problemlos folgenden Code korrekt Interpretieren:
>>> putchar("*tFoo*0bar!*r*n*r*t*tNaechste zeile! *nZwei Sterne: ***n!")
Zu `special_chars` kommt noch die Übersetzung '**' -> '*' dazu, oder kann man den '*' in B gar nicht ausgeben, oder nur, wenn danach keines der bekannten Zeichen folgt?
Doch, in B's putchar() konnte man auch ganz normal ein einzelnes '*' wiedergeben, wenn darauf kein "interpretiertes" zeichen kam.
Das kann man relativ gut mit dem heute gebräuchlichen Backslash vergleichen:
"Foo\bar!" => das "\b" wird als backspace interpretiert
"Foo\\bar" => das "" und "\b" werden ausgegeben, der backspace wird nicht interpretiert
.. Demnach brauch man auch kein '**' in die tabelle einfügen, da das "* + zeichen" nur dann interpretiert wird, wenn auf das '*' auch ein zugeordnetes zeichen folgt! (ich hoffe es war klar worauf ich hinaus wollte ...
)
Code: Alles auswählen
In [14]: special_chars
Out[14]:
{'**': '*',
'*0': '\x00',
'*a': '\x07',
'*b': '\x08',
'*f': '\x0c',
'*n': '\n',
'*r': '\r',
'*t': '\t'}
In [15]: s = 'Hallo*n' + 'Keine Ersetzung: *x*n' + 'Einfacher Asterisk: **'
In [16]: print re.sub(r'\*[*ntrbaf0]', lambda m: special_chars[m.group(0)], s)
Hallo
Keine Ersetzung: *x
Einfacher Asterisk: *
Das ginge natürlich auch, das problem hierbei ist, wie bei allen arbeiten mit regulären ausdrücken, dass diese bei grossen dateien sehr lange dauern können (auch wenn das für die gezeigten beispiele irrelevant ist.)
Zugegebenermassen sieht deine lösung sauberer aus. Aber ich denke nicht, dass sie auch zwingend besser sein muss
Eine Frage bleibt noch: Werden bei B die Zeichen beim Übersetzen ausgetauscht, wie C und Python das machen, oder ist es wirklich die Funktion `putchar()`, die das tut?
Kann ich dir leider nicht beantworten, da B eine sehr alte programmiersprache ist, und es kaum verfügbare quelltexte gibt.
Ich vermute, dass `putchar()` diese zeichen ersetzt, da B nur sehr wenige eingebaute funktionen besitzt.
Aber das wäre echt interessant zu erfahren ...
@martin101986: Ziemlich ineffizient.
Kann ich nicht zustimmen. Folgender code funktioniert hier prima:
Code: Alles auswählen
import sys
def putchar(chars, out=sys.stdout, enc='utf-8'):
special_chars = {'*n': '\012',
'*t': '\011',
'*r': '\015',
'*b': '\010',
'*a': '\007',
'*f': '\014',
'*0': '\000'}
nchars = ''
for key in special_chars.keys():
if key in chars:
chars = chars.replace(key, special_chars[key])
out.write(unicode(chars, enc))
putchar("*tFoo*0bar!*r*n*r*t*tNaechste zeile! *nZwei Sterne: ***n!")