Hi,
in einem avr Programm hat man die Strings ja in der Regel als PSTR().
Wie macht man so ein Programm mehrsprachig ?
Die Sprache muss nicht wechselbar sein (das Programm würde dann auch
durch die vielen Strings zu gross werden), sondern für jede Sprache soll
eine eigene Version compiliert werden.
danke
Sebastian
>Wie macht man so ein Programm mehrsprachig ?
Nun, für Anfänger fangen wir da mal ganz einfach an:
1. In einem String steht "Hello world".
Das ist Englisch. Gut, nich?
2. Ändern wir den String zu "Helpo world".
Das ist ein Wortspiel, immer noch Englisch. Gut ne?
3. Korrigieren wir den String zu "Salut monde".
Das ist kein Englisch. Das mögen die Franzosen nicht.
Ist Fränzösisch. Eine andere Sprache. Pas mal, nes pas?
Das ist doch, das was Du wolltest oder? Einen Text in eine andere
Sprache umsetzen?
Was war jetzt nochmal das Problem?
Das kommt etwas drauf an: wieviele Sprachen, kommen später
welche dazu, wie einfach/ausfuchst soll es ein....
Ein schlichter und praktikabler Ansatz könnte etwa so aussehen
(noch um ein paar PROGMEM etc. bereichert):
prg.c:
Huch schrieb:> Was war jetzt nochmal das Problem?
wenn ich alle Texte im Programm austausche ist es doch deswegen nicht
mehrsprachig.
Versuch erstmal mal mein Problem zu verstehen.
Klaus Wachtler schrieb:> Das kommt etwas drauf an: wieviele Sprachen, kommen später> welche dazu, wie einfach/ausfuchst soll es ein....>> Ein schlichter und praktikabler Ansatz könnte etwa so aussehen> (noch um ein paar PROGMEM etc. bereichert):
an sowas hab ich auch schon gedacht, gefällt mir aber irgendwie nicht.
Gibts nicht vielleicht irgenwelche Makros mit denen man das so basteln
kann, das zumindest der Text einer Sprache, im Programm-Code sichtbar
bleibt und nur die anderen Sprachen in Header-Files stehen ?
>Versuch erstmal mal mein Problem zu verstehen.
Umgekehrt wird ein Schuh, daraus. Versuche Du erstmal Dein Problem
korrekt zu beschreiben. Du willst ja was von uns.
Eine Frage wie nach einem "Designpattern" ist da schon viel hilfreicher,
weil auch ein anderes Niveau anzunehmen ist. Ein Anfänger fragt nicht
nach "Designpatterns". Aber so klang das für mich nach: Wie definiert
man zwei verschiedene konstante Strings.
Huch schrieb:>>Versuch erstmal mal mein Problem zu verstehen.> Umgekehrt wird ein Schuh, daraus. Versuche Du erstmal Dein Problem> korrekt zu beschreiben. Du willst ja was von uns.>> Eine Frage wie nach einem "Designpattern" ist da schon viel hilfreicher,> weil auch ein anderes Niveau anzunehmen ist. Ein Anfänger fragt nicht> nach "Designpatterns". Aber so klang das für mich nach: Wie definiert> man zwei verschiedene konstante Strings.
sorry, aber deine Antwort war einfach komplett sinnloser Müll. Soeinen
Käse würd ich nichtmal nem Anfänger erzählen, es sei denn ich will ihn
verarschen.
Meine Frage war konkret genug um darauf eine sinnvolle Anwort zu geben,
wie dies zB. Klaus ja getan hat.
Sebastian Böhm schrieb:> Klaus Wachtler schrieb:> ...> an sowas hab ich auch schon gedacht, gefällt mir aber irgendwie nicht.
Jetzt bin ich aber fast beleidigt.
>> Gibts nicht vielleicht irgenwelche Makros mit denen man das so basteln> kann, das zumindest der Text einer Sprache, im Programm-Code sichtbar> bleibt und nur die anderen Sprachen in Header-Files stehen ?
Das gibt es auch.
Dazu schreibst du dir z.B. den deutschen Text hin, und läßt
für die anderen Sprachen ein Programm rüberrackern, das alle
deutschen Texte durch andere ersetzt, wenn es einen passenden
Eintrag in einer Tabelle hat.
Das kann man direkt machen, oder indem man den zu ersetzenden
Text noch speziell markiert printf( I18N("hallo") ).
Aber das gefällt mir dann wieder nicht (was dir egal sein
dürfte).
Ein Mittelweg ist, das so wie oben mit den Makros zu machen
und den Makros halt Namen zu geben, aus denen der Text
ersichtlich ist. Macht ja nix, wenn sie etwas länger werden.
Hallo Sebastian,
mit gettext http://de.wikipedia.org/wiki/GNU_gettext kann man sowas
machen. Dein String "Hallo" ersetzt Du durch _("Hallo").
Der String wird dann allerdings zur Laufzeit übersetzt. Das ist auf
einem PC kein Problem, auf einem Atmel frisst das etwas Resourcen.
Wäre das eine Alternative ?
adfix
Klaus Wachtler schrieb:> Das gibt es auch.>> Dazu schreibst du dir z.B. den deutschen Text hin, und läßt> für die anderen Sprachen ein Programm rüberrackern, das alle> deutschen Texte durch andere ersetzt,
optimal wäre es so, das der Text der Primärsprache an Ort und Stelle im
Code steht und die anderen Sprache mittels eines einfaches Switches im
Makefile (also ein define) aktiviert werden können.
Hat da jemand ein fertiges, bewährtes Makro das auch mit PSTR() umgehen
kann?
Huch schrieb:> Wie Du meinst, Sebastian. Ich wollte Dir nur etwas demonstrieren.> Aber scheinbar ist das kein Gewinn für Dich. Lass' ich es also.
deine Demonstration war meiner Meinung nach übertrieben.
Sebastian Böhm schrieb:> Klaus Wachtler schrieb:>> Das gibt es auch.>>>> Dazu schreibst du dir z.B. den deutschen Text hin, und läßt>> für die anderen Sprachen ein Programm rüberrackern, das alle>> deutschen Texte durch andere ersetzt,>> optimal wäre es so, das der Text der Primärsprache an Ort und Stelle im> Code steht und die anderen Sprache mittels eines einfaches Switches im> Makefile (also ein define) aktiviert werden können.>> Hat da jemand ein fertiges, bewährtes Makro das auch mit PSTR() umgehen> kann?
Das wird so einfach mit einem Makro nicht gehen. Wie Klaus schon meint,
müßtest du dir da ein Programm/Skript basteln, das sozusagen als
zusätzlicher Präpropzessor über deinen Code geht und die Strings vor
Übergabe an den Compiler ersetzt.
Dann kann man auch gettext (ohne die Laufzeitkomponente) verwenden, um
die Übersetzungen zu erzeugen.
Sebastian Böhm schrieb:> optimal wäre es so, das der Text der Primärsprache an Ort und Stelle im> Code steht
Der Grund, weswegen mir das nicht so gefällt ist, ist der:
Ich kann mir durchaus Situationen vorstellen, wo ein kurzer
knapper Text unterschiedlich zu übersetzen wäre, je nach
Situation, in der er steht.
Nach deiner Vorstellung wäre er aber nur anhand seines
Wortlauts immer gleich zu übersetzen.
Gerade weil dann aber die fremdsprachliche Variante
wahrscheinlich nie mehr von einem entsprechend Sprachkundigen
so genau angeschaut wird, bevor es zum Kunden geht, habe ich
dabei etwas Magenschmerzen.
Bei der #define-Variante überlegt man sich die Übersetzung
hoffentlich zu einem Zeitpunkt, wo man die konkrete
Programmsituation vor Augen hat.
Deswegen sollst du jetzt nicht auf deine Vorstellung
verzichten, für dich mag es anders aussehen.
Sebastian Böhm schrieb:> Huch schrieb:>> Wie Du meinst, Sebastian. Ich wollte Dir nur etwas demonstrieren.>> Aber scheinbar ist das kein Gewinn für Dich. Lass' ich es also.>> deine Demonstration war meiner Meinung nach übertrieben.
Mag sein, aber Du kennst sicher den Spruch, das nur gehört/gelesen wird,
wer übertreibt.
Andererseits hast Du mich ja garnicht darum gebeten Dir was zu
demonstrieren. Tut mir leid, wenn ich Dich gestört haben sollte. Lebe
und denke einfach so weiter, als sei nichts gescheh'n und alles in
Ordnung.
Wird schon stimmen.
Rolf Magnus schrieb:> Das wird so einfach mit einem Makro nicht gehen. Wie Klaus schon meint,> müßtest du dir da ein Programm/Skript basteln, das sozusagen als> zusätzlicher Präpropzessor über deinen Code geht und die Strings vor> Übergabe an den Compiler ersetzt.> Dann kann man auch gettext (ohne die Laufzeitkomponente) verwenden, um> die Übersetzungen zu erzeugen.
ja ok, so werd ichs machen.
ich werd die strings markieren: /*TEXTID:1*/PSTR('xxx'), so das das
Skript sie findet auch wenn ich den Original Text geändert habe.
Wenn ich Dich richtig verstehe, willst Du zwar alle Sprachen im
Quelltext vorbereitet haben, aber die jeweilige Sprachversion erst beim
Compilieren festlegen. Ist das richtig?
z. B. sowas:
1
#ifdef deutsch
2
#define TEXT_INTRO_HALLO "Willkommen zu dem tollen Programm"
3
#define TEXT_NAME_FMT_S_ALTER_FMT_D "Mein Name ist %s, mein Alter ist %d"
4
#endif
5
6
#ifdef englisch
7
#define TEXT_INTRO_HALLO "Hi"
8
#define TEXT_NAME_FMT_S_ALTER_FMT_D "My name is %s and I am %d years old"
9
#endif
10
11
#ifdef tschechisch
12
#define TEXT_INTRO_HALLO "Ahoj"
13
#define TEXT_NAME_FMT_S_ALTER_FMT_D "Jmenuji se %s a je mi %d let"
14
#endif
Im Makefile musst Du dann nur noch "deutsch", "englisch", "tschechisch"
oder was auch immer definieren. (Ich bin jetzt zu faul zum Nachschauen,
wie.)
Verwenden kannst Du das dann so:
Klaus Wachtler schrieb:> Der Grund, weswegen mir das nicht so gefällt ist, ist der:> Ich kann mir durchaus Situationen vorstellen, wo ein kurzer> knapper Text unterschiedlich zu übersetzen wäre, je nach> Situation, in der er steht.
wie ich in meinem letzten Postion beschrieben habe, bekommt ja jeder
Text eine ID, so das das Problem gelöst ist.
>> Nach deiner Vorstellung wäre er aber nur anhand seines> Wortlauts immer gleich zu übersetzen.
mir schon klar das das nicht geht.
trotzdem danke für deine Hilfe, meine wichtigste Priorität ist aber das
ich nicht immer noch in eine zweite Datei schauen muss um den exakten
Text zu sehen, der Code soll auch gleich Primärquelle für die
Primärsprache sein.
Wenn ich dann zB. einen Text so ändere, das klar ist das die Übersetzung
nicht mehr passt, brauch ich nur die ID zu verändern, somit wird dann
auch automatisch eine neue Übersetzung fällig.
Ich denke dieses Konzept hat keine Nachteile (ausser das man es nicht
nur über defines macht und somit halt noch ein Skript braucht, was aber
trivial ist)
Edi R. schrieb:> z. B. sowas:> #ifdef deutsch> #define TEXT_INTRO_HALLO "Willkommen zu dem tollen Programm"> #define TEXT_NAME_FMT_S_ALTER_FMT_D "Mein Name ist %s, mein Alter ist %d"> #endif>> #ifdef englisch> #define TEXT_INTRO_HALLO "Hi"> #define TEXT_NAME_FMT_S_ALTER_FMT_D "My name is %s and I am %d years old"> #endif>> #ifdef tschechisch> #define TEXT_INTRO_HALLO "Ahoj"> #define TEXT_NAME_FMT_S_ALTER_FMT_D "Jmenuji se %s a je mi %d let"> #endif
In diesem Ansatz sieht man schon den größten Nachteil dieser Methode.
Ich muss immer eine Übersetzung finden, in der die Reihenfolge der
einzusetzenden Substrings passt.
Es kann aber durchaus Sprachen geben, bei denen eine korrekte
Übersetzung eine Umstellung der Teilstrings notwendig macht.
Wenn das Programm mit allen Sprachen nicht ins Memory paßt,
mach doch einfach folgendes:
Für jede Sprache eine eigene Text-Datei, die eingebunden wird.
Die Dateien sehent dann so aus: (Beispiel)
Deutsche Datei:
Text_label_1: "Hallo Welt"
Text_label_2: "es regnet "
Englische Datei:
Text_label_1: "hallo world"
Text_label_2: "it is raining"
Im Programm wird über das Label der Text aufgerufen
print Text_label_1;
Funktioniert prima, Vorsicht ist allerdings bei den Textlängen
angesagt, die müssen halt passen.
Bei umschaltbaren Sprachen, wenn das Memory reicht:
Texte als Array definieren und der Index ist die Sprache.
Habe das mehrfach mit Erfolg eingesetzt.
(C-Compiler von Keil für 8051, sollte beim AVR aber auch gehen)
Guter Rat schrieb:> Für jede Sprache eine eigene Text-Datei, die eingebunden wird.> Die Dateien sehent dann so aus: (Beispiel)>> Deutsche Datei:>> Text_label_1: "Hallo Welt"> Text_label_2: "es regnet ">>> Englische Datei:> Text_label_1: "hallo world"> Text_label_2: "it is raining"
ich weis, ich hätte aber gern den Text einer der Sprachen, direkt um
Code stehen.
Εrnst B✶ schrieb:> puts(TEXT("Hallo Welt","Hello World"));
das ist eigentlich auch nicht schlecht.
optimal wäre jedoch ein makro, wo nur eine Sprache direkt im puts()
steht und alle anderen texte in einem headerfile.
Sebastian Böhm schrieb:> ich weis, ich hätte aber gern den Text einer der Sprachen, direkt um> Code stehen.
Kannst du da nicht einfach Kommentare anwenden? Es ist doch irgendwie
unpraktisch, einen hart-codierten String hernach durch einen anderen zu
ersetzen.
Sebastian Böhm schrieb:> wie ich in meinem letzten Postion beschrieben habe, bekommt ja jeder> Text eine ID, so das das Problem gelöst ist.
Wenn du dem Text sowieso eine ID gibts, kannst du auch gleich zur
Makrolösung greifen.
> trotzdem danke für deine Hilfe, meine wichtigste Priorität ist aber das> ich nicht immer noch in eine zweite Datei schauen muss um den exakten> Text zu sehen, der Code soll auch gleich Primärquelle für die> Primärsprache sein.
Dann schreib dir den deutschen Text als Kommentar dazu.
Du hast sowieso immer das Problem, dass dir die Texte auseinanderlaufen
werden, also kannst du auch den Text im Kommentar vermerken
> Wenn ich dann zB. einen Text so ändere, das klar ist das die Übersetzung> nicht mehr passt, brauch ich nur die ID zu verändern, somit wird dann> auch automatisch eine neue Übersetzung fällig.
Du hast noch nie Programme übersetzt :-)
Die Hauptprobleme bei Übersetzungen sind:
* Textlängen
Du hast Schirmlayouts (egal ob LCD oder ein Windows-Dialog) auf
bestimmte Textlängen hingetrimmt.
In einer anderen Sprache ist der eigentlich richtige
Übersetzungstext aber länger. D.h. dein komplettes Layout kommt dir
durcheinander.
* unterschiedlicher Satzbau
unterschiedliche Sprachen haben auch unterschiedliche Eigenheiten,
wie Sätze korrekt gebildet werden. Da tauschen dann auch schon mal
in den Text einzubauende variable Teile die Plätze.
* kulturelle Unterschiede
Beispiel: Bei uns ist es bei der Ausgabe eines Namens meistens üblich
den Vornamen vor den Familiennamen zu schreiben. Drum heißt das Teil
ja auch Vorname.
Als ich das bei einem Wettbewerb natürlich auch mit ein paar Chinesen
gemacht habe, wurde ich sofort korrigiert. Dort ist der Familienname
das wichtigste. Und erst dann kommt der Vorname der Person. Bei uns
spielt das keine grosse Rolle, aber Chinesen stehen drauf.
* ganz banale Dinge, wie zb
wir verwenden ein Dezimalkomma. Amerikaner einen Dezimalpunkt
(und lass dich ja nicht darauf ein, Tausenderpunkte zu setzen. Gibt
nur Ärger! Vor allen dann in Eingaben)
Datum: Tag/Monat/Jahr versus
Monat/Tag/Jahr versus
Jahr/Monat/Tag
übliche Uhrzeitangabe: 24 Stunden oder 12 Stunden mit AM/PM Angabe
(viele Ami kann man mit einer 24 Stunden Angabe komplett
verwirren)
Karl heinz Buchegger schrieb:> Dann schreib dir den deutschen Text als Kommentar dazu.
wenn ich in der Primärsprache was ändere, will ich nicht den Text in
zwei Dateien ändern müssen. Daher soll ein Text, direkt da stehen.
> Du hast noch nie Programme übersetzt :-)
doch hab ich, nur nicht in C.
Wie man sowas vom Umgang mit den Texten her handelt und was da die
Standard Probleme sind weis ich, ich such nur nach einer technischen
Lösung, die meine Ansprüche erfüllt.
Bei diesem Projekt kommen nur einzelne Worte vor, keine Sätze.
Es handelt sich dabei nur um eine Menüstruktur auf dem Display und
einzelne kurze Meldungen. (sowas wie: "Error: connection lost")
Jeder Text bekommt ne ID, wenn ein solcher Text sich im Original
ändernt, bekommt der übersetzter das mit, er sieht dann den alten Text
(den er schonmal übersetzt hat) und den neuen Text. Hinweise wie
maximale länge, kann er natürlich auch sehen. Ausserdem liegen ihm
Screenshots von allen Programmsituationen vor in denen die Text-IDs zu
sehen sind. Aber wie gesagt die Prozess-Abläufe bei der eigentlichen
Übersetzung sind bereits ausgereift.
Sebastian Böhm schrieb:> Jeder Text bekommt ne ID, wenn ein solcher Text sich im Original> ändernt, bekommt der übersetzter das mit,
Wie bekommt er das denn mit?
> er sieht dann den alten Text> (den er schonmal übersetzt hat) und den neuen Text.
Hast du die entsprechenden Tools dafür?
Für Windows hab ich früher gerne WinTrans benutzt. Das macht genau
sowas. Aber auch dieses Tool ist darauf angewiesen, dass man Texte als
Textresource anlegt und auch so verwendet.
> Hinweise wie> maximale länge, kann er natürlich auch sehen.
Wow.
Und wer pflegt das alles?
Das man das alles mit den richtigen Tools machen kann - zweifellos. Die
Frage ist immer: wie praxistauglich ist das alles. Nicht heute, nicht
morgen. Sondern in einem halben oder ganzen Jahr :-) Dort wird es dann
nämlich interessant, wie gut der Prozess dann noch gepflegt wird.
Selbst mit WinTrans blieben dann noch Leichen im Keller.
Aber im Endeffekt: Du hast die Entscheidungsgewalt. Ich kann nur auf
Dinge hinweisen, die mir untergekommen sind.
Karl heinz Buchegger schrieb:> Sebastian Böhm schrieb:>>> Jeder Text bekommt ne ID, wenn ein solcher Text sich im Original>> ändernt, bekommt der übersetzter das mit,>> Wie bekommt er das denn mit?
das zeigt ihm die Software.
>>> er sieht dann den alten Text>> (den er schonmal übersetzt hat) und den neuen Text.>> Hast du die entsprechenden Tools dafür?
ja. selbstentwickelt.
> Wow.> Und wer pflegt das alles?
ist kein Problem.
> Das man das alles mit den richtigen Tools machen kann - zweifellos. Die> Frage ist immer: wie praxistauglich ist das alles. Nicht heute, nicht> morgen. Sondern in einem halben oder ganzen Jahr :-) Dort wird es dann> nämlich interessant, wie gut der Prozess dann noch gepflegt wird.
funktioniert gut, die Prozesse sind eingespielt, das läuft hier so schon
seit 10 Jahren.