Liege ich hier komplett falsch oder wird hier von einem Wert die Kommastelle bestimmt char cDataOut[11]; cDataOut[1] = x / 1000 + 48; cDataOut[2] = fmod(x, 1000) / 100 + 48; cDataOut[3] = fmod(x, 100) / 10 + 48; cDataOut[4] = fmod(x, 10) + 48; cDataOut[5] = 0x2c; // ',' cDataOut[6] = y / 1000 + 48; cDataOut[7] = fmod(y, 1000) / 100 + 48; cDataOut[8] = fmod(y, 100) / 10 + 48; cDataOut[9] = fmod(y, 10) + 48; cDataOut[10] = 0x3b; // ';' cDataOut[11] = '\0'; putsUART1((unsigned int *) cDataOut); return 0; }
Hi gre bre, ja, Du liegst falsch. Hier passiert zweierlei: Das schlimmste zuerst: Es wird außerhalb des vereinbarten Arrays cDataOut im Speicher ein 0-Byte abgelegt. Die Arrayindices von cDataOut gehen nicht von 1 bis 11 sondern von 0 bis 10!!! Als zweites wird hier ein float-Wert, der aus einem (vermutlichen) int für die Vorkommastellen und einem zweiten int für die Nachkommastellen mit jeweils 4 Stellen in einen ASCII-String gewandelt. Format: vvvv,nnnn;\0 Zur eigentlichen Vorgehensweise sage ich besser nichts, ich kenne die Umgebung nicht. Es gibt in C/C++ wesentlich effizientere Methoden. Markus
Du hast recht am Hyperterminal werden Daten in diesem Format 0000,0085;0001,0087;......ausgegeben.
Kennst du vielleicht eine gute Seite wo man das nachlesen kann oder unter welchen Suchbegriff das zu finden ist
Hi gre bre, es werden bestimmt bald Aufschreie aus der C++-Abteilung kommen, aber das kompakteste, das ich kenne, ist in diesem Fall sprintf: sprintf(cDataOut,"%04d,%04d;",x,y); Kompakter geht es meiner Meinung nach nicht. Dadurch sieht man auch auf einen Blick, was hier passiert. Ein Problem gibt es bei der Konvertierung, das gilt aber für alle Lösungen. Es muß sichergestellt sein, daß x und y nur im Wertebereich von 0 <= x,y <= 9999 liegt. Sonst schreibt die Software wieder in Speicherbereiche, in denen sie nichts verloren hat. Ich habe heute Morgen leider zu wenig Zeit, um noch ausführlich auf weitere Lösungen einzugehen. Ich denke, daß zu diesem Thema sicher andere auch etwas beitragen werden. Falls nichts mehr kommt, werde ich heute Abend mal schauen, wo es noch klemmt. Ach ja, Du hast auch noch nach Suchbegriffen gefragt: Englisch formatting, ggf. auch streams (wegen den C++-Profis ;-)), deutsch dann Formatierung Gruß Markus
vielleicht hört sich das für einen profi in C++ dumm, an aber wie werden die werte von 0-9999 begrenzt
Hallo gre bre, dumme Fragen gibt's nicht, nur dumme Antworten. Bei der Begrenzung gibt es, wie fast immer beim Software entwickeln, viele Möglichkeiten. Die einfachste ist die, wenn dort, wo x und y gesetzt werden, sichergestellt ist, daß deren Wertebereich tatsächlich nur von 0 bis 9999 gehen kann, weil x und y einen Punkt in einem entsprechenden Koordinatensystem darstellen. Ansonsten VOR der Konvertierung den Wertebereich abprüfen und im negativen Fall einen Fehler erzeugen: if ( x >= 0 && x <= 9999 && y >= 0 && y <= 9999 ) { sprintf(...); } else { // Fehler melden, in C++ ggf. eine Exception auslösen } Wie Du das in Deinem Code letztendlich umsetzt, hänge sehr stark von den Gegebenheiten ab. So könnten z.B. x und y unsigned sein, dann ist der Test auf ">= 0 überflüssig. Es wäre auch möglich, den Sting cDataOut so groß zu machen, daß auf jeden Fall beim Konvertieren kein Bufferoverflow stattfinden kann. Ein 32-Bit-int hat als Dezimalzahl max. 11 Stellen, mit Vorzeichen 12. Das Ganze mal 2 und noch die Zeichen ",", ";" und die 0 am Ende, macht zusammen 25 Zeichen. Wenn Du char cDataOut[32] deklarierst, bist Du auf der sicheren Seite. Gruß Markus
Licht am Ende des Tunnel mit deiner Unterstützung kann man den Sting cDataOut beliebieg groß machen noch einmal wie kommst du auf die 0-9999 und dann glaube habe ichs nochmals danke für deine unterstützung
Hallo gre bre, cDataOut kann man fast beliebig groß machen. Fast soll heißen, daß die Größe i.d.R. durch den Stack, die Größe des Heaps (dynamischer Datenspeicher), die Größe des tatsächlichen Arbeitsspeichers und normalerweise durch den 32-Bit-Integerbereich von Größenangaben beschränkt. Große Datenpuffer, also auch Strings sollte man in C++ mit new allokieren, mit delete wieder freigeben. In C geht das mit malloc/calloc und free. char *cDataOut = malloc(100000); // 100000 Bytes Speicher anfordern ... free(cDataOut); Allerdings ist hier sehr große Disziplin angesagt. Es ist eine der häufigsten und vor allem am schwierigsten zu findenden Fehlerquelle in C/C++, wenn Speicher zwar allokiert, aber nicht wieder frei gegeben wird. char* cDataOut = malloc(1000); ... cDataOut = malloc(2000); ... free(cDataOut) Die ersten tausend Bytes sind bis zum nächsten Programmstart unwiederbringlich futsch. Wenn man das in einer Schleife veranstaltet, platzt recht bald der Heap. Zur Frage nach dem begrenzten Wertebereich: Wenn man das Programm etwas genauer anschaut, sieht man, daß für den String im Format "xxxx,yyyy;" ein String mit genau 11 Bytes vorgesehen wurde. Ein Byte für die abschließende 0, ein Komma, ein Semikolon. Bleiben noch 8 Bytes für die beiden Zahlen. Macht je 4 Stellen, also 0 bis 9999. Dies ist aber nur ein Indiz. In Programmcode passiert folgendes: cDataOut[1] = x / 1000 + 48; In dieser Zeile wird eine ganzzahlige Division durch 1000 durchgeführt, dann das ASCII-Zeichen '0' dazu addiert. 0 / 1000 = 0, + '0' = '0'. 999 / 1000 = 0, ..., 1000 / 1000 = 1, + '0' = '1', ... cDataOut[2] = fmod(x, 1000) / 100 + 48; fmod ermittelt den ganzzahligen Divisionsrest von x / 1000, beide werden erst mal in float-Werte konvertiert. Dann Wird durch 100 geteilt und wieder '0' dazu addiert. Effektiver geht das übrigens so: char hunderter = ( x / 100 ) % 10 + '0'; // ohne float-Konvertierung cDataOut[3] = fmod(x, 100) / 10 + 48; cDataOut[4] = fmod(x, 10) + 48; Den Rest kannst Du Dir ja selbst ermitteln. Jedenfalls werden x und y 4-stellig nach cDataOut konvertiert. Gruß Markus
sprintf(cDataOut,"%04d,%04d;",x,y); hier in deiner verkürzten schreibweise passiert das gleiche Herzlichen Dank für deine Bemühungen
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.