Hallo, eine kleine Frage: Ich möchte mehrere einzelne Strings aneinander hängen. DisplayRAM = "Drehzahl: " " U/min " "Spannung: " "Volt " ; Das geht auch so weit ganz gut. Nur wie kann ich jetzt dieses erzeugen? volatile unsigned int Zahl = 0; volatile unsigned char string[5]; ... itoa( Zahl, string, 10); DisplayRAM = "Drehzahl: " string " U/min " "Spannung: " string "Volt " ; Ich möchte also zum String die Werte der Zahl einfügen. Gruß Toby
sprintf()/snprintf(), oder die Teile einzeln mit strcat()/strncat() zusammenfügen. In jedem Falle musst du einen Zielpuffer bereitstellen, der genügend Platz hat.
Deine aneinandergehängten Strings sind nicht wirklich aneinandergehängte Strings, sondern eine einzige große Stringkonstante. Um das Zusammenfügen kümmert sich bereits der Preprocessor. Um sich verändernde Werte an Strings anzuhängen, muss eine andere Vorgehensweise verwendet werden. Einerseits benötigst Du einen ausreichend großen Puffer, der das Endergebnis aufnehmen soll, andererseits musst Du geeignete Funktionen zur Stringverarbeitung verwenden.
1 | char buf[100]; // muss ausreichend groß sein! |
2 | char string[6]; // muss für Ausgabe von unsigned int reichen |
3 | |
4 | |
5 | itoa(Zahl1, string, 10); |
6 | |
7 | buf[0] = '\0'; |
8 | |
9 | strcat(buf, "Drehzahl: "); |
10 | strcat(buf, string); |
11 | strcat(buf, " U/min "); |
12 | strcat(buf, " Spannung: "); |
13 | |
14 | itoa(Zahl2, string, 10); |
15 | strcat(buf, string); |
16 | |
17 | strcat(buf, "Volt "); |
(die Formatierung der Leerzeichen etc. solltest Du Dir nochmal näher ansehen). Bei Aufruf von itoa mit einem unsigned Int muss der übergebene Puffer übrigens Platz für sechs und nicht nur für fünf Zeichen bieten - ein unsigned int selbst kann eine fünfstellige Zahl sein, und die stringterminierende Null muss auch noch Platz finden. Wenn ausreichend Programmspeicher zur Verfügung steht, lässt sich natürlich auch ein printf-Derivat einsetzen, was den Vorteil der auf definierbare Feldbreiten formatierten Ausgabe der numerischen Werte hätte.
Hallo, müsste es dann so aussehen? strcat("Drehzahl: ", &string, &" U/min ", &"Spannung: ", &string, &"Volt "); sprintf()/snprintf() möchte ich nicht nutzen, da ich dafür schon keinen Platz mehr im Programm habe. Gruß Toby
Nein, strcat hat exakt zwei Argumente. Den Adressoperator solltest Du übrigens auch weglassen. Du musst also strcat für jedes anzuhängendes Stringfragment erneut aufrufen - wobei es Dir unbenommen bleibt, Stringkonstanten automatisch vom Preprocessor zusammenfassen zu lassen (U/min und Spannung). Sofern Du einen AVR mit seiner praktischen Harvard-Architektur verwendest, solltest Du auch daran denken, daß Stringkonstanten im RAM abgelegt werden. Du solltest also darauf achten, diese via PROGMEM zu deklarieren und zu nutzen, dafür sollte dann ein strcat_P existieren:
1 | char buf[100]; // muss ausreichend groß sein! |
2 | char string[6]; // muss für Ausgabe von unsigned int reichen |
3 | |
4 | |
5 | itoa(Zahl1, string, 10); |
6 | buf[0] = '\0'; |
7 | |
8 | strcat_(buf, PSTR("Drehzahl: ")); |
9 | strcat(buf, string); |
10 | strcat_P(buf, PSTR(" U/min ")); |
11 | strcat_P(buf, PSTR(" Spannung: ")); |
12 | |
13 | itoa(Zahl2, string, 10); |
14 | strcat(buf, string); |
15 | |
16 | strcat_P(buf, PSTR("Volt ")); |
Für Deine zur Laufzeit erzeugten Strings musst Du natürlich das "normale" strcat verwenden.
's ist übrigens der Compiler, der die Konstanten zusammenfasst, nicht der Präprozessor.
Hallo, danke für die schnelle Antwort. ich nutze einen ATmega8, bzw dem ATmega168. Ich brauche also nur die Strings für die dynamischen Werte im Ram legen, die Konstanten (Drehzahl :) z.B. im Flasch, richtig? Gruß Toby
Den Zielstring musst du auch im RAM anlegen, d. h. du brauchst irgendwo irgendwie genügend Platz dafür.
Brauchst du den String eigentlich sicher an einem Stück? Bei RS232 oder LCD-Ausgabe isses normalerweise möglich die Teilstrings einzeln nacheinander auszugeben. also uart_print_P(PSTR("Drehzahl: ")); uart_print_int(drehzahl); uart_print_P(PSTR(" U/min ")); usw. /Ernst
Hallo, ich brauche den String, um ihn auf einem LED Array anzuzeigen. Eine Frage noch, in welcher Lib ist die Funktion "strcat" mit drin? Ich bekomme noch den Fehler: ..../main.c:521: undefined reference to `strcat_' Gruß Toby
> Eine Frage noch, in welcher Lib ist die Funktion "strcat" mit drin? In der libc.a, die automatisch mit gelinkt wird. > ..../main.c:521: undefined reference to `strcat_' Die Funktion heißt auch entweder strcat() oder strcat_P(), aber nicht strcat_().
http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F Und der Kauf, das Durcharbeiten (zumindest der ersten paar Kapitel) eines durchaus handelsüblichen Buches über C ist dringend ans Herz gelegt.
Hallo Jörg, habe es schon gesehen, da fehlte ein P. Es geht jetzt wunderbar! Eine letzte Sache noch: Ich habe es jetzt so geschrieben: volatile uint8_t *DisplayRAM = "Drehzahl: 0000 U/min Spannung: 0,00 Volt "; volatile unsigned int Zahl1 = 0; volatile unsigned int Zahl2 = 0; char buf[64]; // (habe max.64 Zeichen) char string[6]; // muss für Ausgabe von unsigned int reichen itoa(Zahl1, string, 10); buf[0] = '\0'; strcat_P(buf, PSTR("Drehzahl: ")); strcat(buf, string); strcat_P(buf, PSTR(" U/min ")); strcat_P(buf, PSTR("Spannung: ")); itoa(Zahl2, string, 10); strcat(buf, string); strcat_P(buf, PSTR(" Volt ")); DisplayRAM = buf; Angezeigt wird nun: "Drehzahl: XXXX U/min Spannung: XXX Volt " wie bekomme ich nun noch hier: ^ ein Komma dazwischen? "Drehzahl: XXXX U/min Spannung: X,XX Volt " Da muß ich doch diese Funktion : itoa(Zahl2, string, 10); strcat(buf, string); zerlegen, nach den ersten Ziffern ein "," schreiben, und dann die letzten Ziffern, richtig? Gruß Toby
Hallo Karl Heinz, ich habe schon ein C Buch (C für Mikrocontroller, von Franzis), allerdings ist es nicht so toll, da mir eigentlich immer die Beispiele genau zu meinem Problem fehlen. Wenn ich die Beispiele hier lese, verstehe ich es eigentlich recht schnell. Ich nutze ja meistens auch die Suchfunktion, bevor ich etwas spezielles frage. ;-) Trotzdem danke. Gruß Toby
TobyTetzi wrote: > volatile uint8_t *DisplayRAM = "Drehzahl: 0000 U/min > Spannung: 0,00 Volt "; Das volatile ist hier sehr wahrscheinlich überflüssig (und könnte dir umständlichen Code erzeugen). Der Datentyp darstellbarer Zeichen sollte immer als "char" deklariert werden. > volatile unsigned int Zahl1 = 0; > volatile unsigned int Zahl2 = 0; Stellt sich ebenfalls die Frage, wofür das volatile hier gut ist. > Angezeigt wird nun: > > "Drehzahl: XXXX U/min Spannung: XXX Volt " > > wie bekomme ich nun noch hier: ^ ein Komma dazwischen?
1 | #include <stdlib.h> |
2 | |
3 | ...
|
4 | div_t d; |
5 | |
6 | d = div(Zahl2, 10); |
7 | itoa(d.quot, string, 10); |
8 | strcat(buf, string); |
9 | strcat_P(buf, PSTR(",")); |
10 | itoa(d.rem, string, 10); |
11 | strcat(buf, string); |
12 | strcat_P(buf, PSTR(" Volt ")); |
13 | |
14 | ...
|
Zwar benutzt div() vorzeichenbehaftete Integerzahlen, während deine Werte unsigned sind, aber itoa() benutzt ebenfalls int. Wenn du also Werte größer als 32767 hast, musst du das sowieso anders angehen.
TobyTetzi wrote: > "Drehzahl: XXXX U/min Spannung: XXX Volt " > > wie bekomme ich nun noch hier: ^ ein Komma dazwischen? > > "Drehzahl: XXXX U/min Spannung: X,XX Volt " > > Da muß ich doch diese Funktion : > itoa(Zahl2, string, 10); > strcat(buf, string); > zerlegen, nach den ersten Ziffern ein "," schreiben, und dann die > letzten Ziffern, richtig? Das ist eine Möglichkeit, das ',' im Nachhinein in den String einzuschmuggeln, ja. Eine andere Möglichkeit: Wieviel ergibt 523 / 10? Richtig, das macht 5 Und was ergibt 523 % 10? Genau, das macht 23 Wenn du also zuerst die 5 ausgibst, dann ein Komma und dann die 23, steht auf deinem Display: 5,23 (Die führenden Nullen bei der Modulo Division nicht vergessen: 507 % 10 macht 7! D.h. bei der Ausgabe muss zuerst 5, dann ein Komma, dann eine 0 und dann erst die 7 ausgegeben werden)
TobyTetzi wrote: > Hallo Karl Heinz, > > ich habe schon ein C Buch (C für Mikrocontroller, von Franzis), > allerdings ist es nicht so toll, da mir eigentlich immer die Beispiele > genau zu meinem Problem fehlen. Die wirst du auch in keinem Buch finden. Programmieren lebt davon, dass man Bausteine kombinieren kann. Bausteine können sein: Arithmetische Anweisungen kein µC kann aus einer Zeitdifferenz eine Frequenz berechnen. Aber es gibt die Operation 'Division'. Und wenn man jetzt noch weiss, dass f = 1 / t dann hat man das Problem durch Kombination von 2 'Bausteinen' gelöst Algorithmen Für viele Problemstellungen gibt es Standardverfahren. Ein gutes Buch führt einen auf spielerische Art und Weise in die wichtigsten und häufigsten Algorithmen ein, indem sie entweder besprochen oder aber als Idee skizziert und als Übungsaufgabe gestellt werden. Drum ist das Durcharbeiten von Übungsaufgaben in einem Programmierbuch auch so wichtig. Standardbibliotheken Einige (meist einfache) Algorithmen sind von so fundamentaler Bedeutung, dass mit dem Programmiersystem auch entsprechende vorgefertigte Funktionen mitgeliefert werden. Die sollte man kennen und mit ihnen (im Rahmen von Übungsaufgaben) auch mal gearbeitet haben, damit man sich an sie erinnert wenn man sie braucht. Dreh und Angelpunt ist aber immer wieder eines: Programmieren lernt man nur durch Programmieren. Ein Buch einfach nur durchzulesen ist vergeudete Zeit. Man muss das, was man gelesen hat auch sofort in einem Programm umsetzen, eventuell etwas abwandeln um zu sehen, was man sonst noch mit der präsentierten Idee machen kann. Nur so lernt man und merkt sich auch, welche Funktionen es gibt, wie sie eingesetzt werden und welche Ideen dahinter stecken. Dann hat man seine Bausteine im Kopf parat und kann sie abrufen wenn man sie braucht. Das Buch braucht man dann nur noch, um Details die man sich nicht gemerkt hat, nachschlagen zu können. Was aber nicht heist, dass solche Detail-Nachschlagbücher (auch solche gibt es) für den Anfang empfehlenswert sind. Ganz im Gegenteil.
Karl heinz Buchegger wrote: > Eine andere Möglichkeit: > Wieviel ergibt 523 / 10? Richtig, das macht 5 > Und was ergibt 523 % 10? Genau, das macht 23 Eher "/100" bzw. "%100", gell?
Johannes M. wrote: > Karl heinz Buchegger wrote: >> Eine andere Möglichkeit: >> Wieviel ergibt 523 / 10? Richtig, das macht 5 >> Und was ergibt 523 % 10? Genau, das macht 23 > Eher "/100" bzw. "%100", gell? <Geräusch, das entsteht, wenn die Stirn auf der Tischplatte aufschlägt> Danke.
Karl heinz Buchegger wrote: > <Geräusch, das entsteht, wenn die Stirn auf der Tischplatte > aufschlägt> Na, kein Grund zur Selbstverstümmelung;-) War nur, um sicherzugehen, dass kein unbedarfter Anfänger tatsächlich glaubt, 523 / 10 ist 5... Kannste ja oben ändern und meine beiden letzten Postings löschen... Gruß johnny.m
> War nur, um sicherzugehen, dass kein unbedarfter Anfänger tatsächlich > glaubt, 523 / 10 ist 5... Ein Anfänger in Grundschulmathematik? ;-)
Rolf Magnus wrote: >> War nur, um sicherzugehen, dass kein unbedarfter Anfänger tatsächlich >> glaubt, 523 / 10 ist 5... > > Ein Anfänger in Grundschulmathematik? ;-) Naja, hier muss man mit allem rechnen...;-)
Hallo, ich habs nun! Jetzt gehts so, wie ich will, das ich auch veränderliche Werte anzeigen kann. Danke an alle, die mir mal mehr, mal weniger mit Rat und Tat zur Seite standen! Hier das Ergebnis: Ein ca. 6MB großes Video. http://www.tobytetzi.de/NightVision/NV2.0Rev7.1.mpg Gruß Toby
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.