Variablen in Variablennamen < Matlab < Mathe-Software < Mathe < Vorhilfe
|
Status: |
(Frage) beantwortet | Datum: | 21:44 Do 19.07.2007 | Autor: | Ceres |
Ich habe diese Frage in keinem Forum auf anderen Internetseiten gestellt.
Ich versuche meine Akkuladestation auszulesen und bin auch schon relativ weit. Aber derzeit habe ich ein Problem, bei dem ich von selbst nicht auf die Lösung gekommen bin.
Ich möchte ein Zeit ausgeben. Die Stunden und Minuten stehen schon in einem Array des entsprechenden Kanals stehen. Die Stunden stehen im 16. Byte, die Minuten im 17. Byte. Ich möchte jetzt diese beiden Daten zusammen mit einem : verbinden, damit ich das Format hh:mm bekomme und ausgeben kann. Hier mal der Quelltext des m-Files:
----------
function [ ] = time(ch)
hour = sprintf('ch%i(16;end)',ch)
min = sprintf('ch%i(17,end)',ch)
sprintf('timech%i = %i:%i',ch,hour,min)
----------
ch ist der Kanal und wird mit dem Aufrufen der Funktion übergeben (z.b. time(4), dann möchte ich die Zeit von Kanal 4).
Immer wenn ich neue Daten von einem Kanal erhalte, werden die als Vektor in ein dem Kanal entsprechendes Array geschrieben (z.b. ch4). Jetzt möchte ich das 16. und 17. Byte des letzten array-Eintrages (daher end) und möchte diese beiden mit dem Doppelpunkt verbinden. Wenn ich das so mache, wie im Quelltext, speichert er nur den Sting in hour und min:
----------
EDU>> time(4);
hour =
ch4(16;end)
min =
ch4(17,end)
ans =
timech4 = 99:104timech52 = 40:49timech54 = 59:101timech110 = 100:41timech99 = 104:52timech40 = 49:55timech44 = 105:110timech100 = 101:120timech99 = 104:52timech45 = 49:41
--------------
Er speichert aber nicht den Inhalt der Bytes darein. Wenn ich das sprintf(' noch vor das hour bzw. min stelle, meckert er, dass 'hour' eine undefinierte Variable oder Funktion ist. Wie kann ich das (an sich nicht schwere) Problem lösen? So dass ich nachher zum Beispiel 6:35 erhalte, für 6 Stunden und 35 Minuten. Wo liegt mein Denkfehler oder kennt jemand noch eine andere Methode?
Mit freundlichen Grüßen
Ceres
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 11:29 Fr 20.07.2007 | Autor: | Peter_Pein |
Hallo Ceres,
ich kenne mich mit matlab zwar überhaupt nicht aus, aber wenn die Formatstrings den aus C bekannten auch nur entfernt ähneln, liegt m.E. folgendes Problem vor:
Du weist per sprintf den Variablen hour und min jeweils einen String zu.
Wenn nun, wie ich vermute, das %i ein Platzhalter für eine Integervariable ist, sollte ein halbwegs sorgsam programmiertes matlab eigentlich meckern, dass in der letzten Zeile versucht wird, einen String per Integerformat abzusondern.
Dass dies augenscheinlich nicht passiert, heißt entweder, dass ich mich täusche, oder dass matlab ziemlicher Schrott ist.
Das erste ist wahrscheinlicher.
Ohne, wie bereits erwähnt, von irgend welcher Sachkenntnis getrübt zu sein, schiene mir dennoch statt
sprintf('ch%i(16;end)',ch)
etwas wie z.B.
sprintf('ch%i',ch(16;end))
einsichtiger; soll heißen: die Indizierung von ch aus dem Formatstring herausholen.
Na ja, bevor ich mich hier weiter in Spekulationen versteige und doch keinen Spekulatius dafür bekomme, wünsche ich Dir lieber viel Glück beim Knobeln.
Peter
|
|
|
|
|
Tach zusammen,
um den schon richtigen ansatz von Peter zu ende zu bringen. Du hast da einfach die funktion sprintf nicht verstanden/richtig angewendet.
Die ausgabe der stunden/minuten einzeln sollte so aussehen(so denn das array tatsächlich die kanäle spaltenweise enthält?!):
%MatlabCode
hour = sprintf('%i',ch(16,end))
min = sprintf('%i',ch(17,end))
%MatlabCode
Um jetzt die stunden und minuten in der gewünschten form also mit doppelpunkt auszugeben sollte folgender code zum ergebnis führen:
%MatlabCode
sprintf('%i:%i',ch(16,end),ch(17,end))
%MatlabCode
Die Funktion von sprintf und die ganzen formatierungsparameter zu erklären ist mir jetzt zu aufwendig, da sag ich mal nur "help sprintf".
regards
funtaonice
|
|
|
|
|
Hi,
einerseits freue ich mich, dass mein Verdacht bestätigt wurde
Andererseits habe ich mir aus gegebenem Anlass GNU-Octave heruntergeladen (sowie octave-workshop, um es unter Win2k erträglich bedienen zu können). Es handelt sich, wenn ich es richtig verstanden habe, um so 'ne Art "MatLab für Leute mit ohne Geld".
Ich habe mit {s|f}printf() experimentiert und es fiel mir auf, dass ich als Nutzer alleinige Verantwortung darüber zu haben scheine, welches Format ich zur Ausgabe eines Wertes eines bestimmten Typs nehme.
Obwohl ich es nicht geregelt bekommen habe, bin ich mir sicher, dass ich, falls z.b. hour per sprintf einen Wert zugewiesen bekam, ich diesen per printf("%s Stunden", hour) auszugeben hätte. Zumindest Octave meckert aber nicht, wenn ich printf("%5.2f stuss", hour) verwende . Es gibt natürlich nur mehr oder weniger zufällig anmutenden Zeichensalat. (Außerdem scheint es in Octave kein "%i" zu geben (wird bei Verwuendung dennoch nicht zurück gewiesen); ich nehme an, "%i" steht für "integer" und entspricht "%d" aus C/Octave)
Ich verstehe das nicht: Im Gegensatz zu einem Compiler weiß ein Interpreter doch genauestens (sorry für stupiden Superlativ), welcher Datentyp einer Variablen zur Laufzeit zugeordnet ist und müßte doch wenigstens(!!) eine Warnung wie zum Bleistift: "Ausgabeformat 'float' passt nicht zu Datentyp 'string'" ausgeben.
So gesehen weiß ich doch als Nutzer auch nícht, was passiert, wenn ich mir 'ne Matrix [2,5,7;3:5:13] definiere und ein Element durch 28.49 ersetze. Hatte ich vorher eine Matrix mit ganzzahligen Elementen, so ist es nun gemischt und wenn ich das Ding ausdrucken lassen möchte muss ich mir merken, dass beispielsweise matrix(2,2) eine Fließkommazahl ist, aber alle anderen Elemente ganzzahlig? Oder gibt es sowas wie 'implicite type casting'? Falls ja, dann nicht innnerhalb meiner ersten Experimente mit Octave
Ich glaube nicht, dass ich daran Freude haben werde. Aber ich will es noch probieren, um zu sehen, ob ich oder die Entwickler etwas Wesentliches übersehen haben
's Peterle
|
|
|
|
|
Moin,
zuerst mal die funktion von s/fprintf aus der matlabhilfe:
sprintf
Write formatted data to string
syntax
[s, errmsg] = sprintf(format, A, ...)
Im prinzip sagt es ja schon alles, prinzipiell gibt die funktion s/fprintf also jeden eingabewert als string aus und zwar unter beachtung der gewälten formatierung.
Im prinzip verwendet man also s/fprintf nur dann, wenn man eine/mehrere variable(n) mit oder ohne zusätzliche zeichen in anderer form als der in z.B. einer matrix abgelegten form ausgeben will.
Das setzt ja schon fast implizit die kentniss des users über die form/typ der variablen vorraus.
Wenn man jetzt wie in matlab ja eigentlich üblich eh nur mit zahlen (in matritzen) arbeitet, macht s/fprintf eigentlich wenig kopfzerbrechen und dient ja "nur" dazu eine für die ausgabe "unhandliche" fließkommazahl z.B. als ganzahligen integer auszugeben, bzw wie in der ausgangsfrage mehrere variablen mit zusätzlichen strings zu versehen.
Lustig wird es allerdings dann wenn man einen string in s/fprintf nicht als string/character formatiert ausgibt sondern in decimal- oder fließkommanotation, dann muss man nämlich (aus der hilfe) wissen, dass matlab dann den character in den ensprechenden ASCII DezimalCode wandelt und ausgibt.
Das einzig wie ich finde inkonsequente ist die fehlerbehandlung. Wenn man z.B. eine fliesskommazahl als integer formatiert ausgeben will (und vorher halt nicht rundet), dann ignoriert matlab die formatierung und gibt die zahl in exponentieller notation aus (das soll dann als fehlerhinweis für den nutzer gelten?!). Ein weiteres beispiel ist wenn ich zahlen als string/character formatiert ausgeben will, solange es sich um ganze zahlen handelt gibt matlab einfach ohne fehlermeldung garnichts aus, wenn es sich um eine fliesskommazahl handelt dann wird als fehlerhinweis diese wieder in exponentieller form ausgegeben.
Über den inkonsistenten typ der eingegebenen variable beschwert sich matlab eigentlich nur, wenn man versucht eine zahl als string formatiert auszugeben. Wobei dabei die inkonsequenz der fehler"meldung" am deutlichsten zu tage tritt. Handelt es sich um eine ganze zahl kommt eine wirklich hilfreiche fehlermeldung "The argument for the %s format specifier must be of type char (a string)". Ist es allerdings eine flieskommazahl wird das formatierungsargument einfach mit %e ersetzt und die zahl in expoentieller notation ausgeben.
Im prinzip muss man die hilfe zu rate ziehen, da sind auch ein paar beispiele angegeben und im zweifelsfall halt etwas rumprobieren.
reagards
funtaonice
|
|
|
|