Hallo Leute, ich stehe gerade etwas auf dem Schlauch mit printf(). String-Ausgabe ist klar. Aber wie kann man damit Strukturen ausgeben? Ich habe eine struct definiert (im RAM) und möchte die quasi als memory-Dump ausgeben. Also aus einem (char)0 soll auch das nichtdruckbare Zeichen werden, nicht '0'. Quasi etwas wie WriteFile(hFile, &struct, sizeof(struct), ...); Ausgangspunkt ist GCC für AVR. Hoffentlich keine Infos vergessen. Die Lösung ist wahrscheinlich trivial, aber printf(struct) gibt immer den Fehler "incompatible type of argument 1". Andy
Hallo ! Schreib dir eine Konvertierungsfunktion für deine Struktur. Da kannst du dann genau anpassen was wie und in welcher Reihenfolge alle Strukturelemente ausgegeben werden. Ergebnis ist ein String dem du dann printf übergibst. L.g. Michi
Andy schrieb: > ich stehe gerade etwas auf dem Schlauch mit printf(). String-Ausgabe ist > klar. Aber wie kann man damit Strukturen ausgeben? printf kannst du nur dann benutzen, wenn es entsprechende Formatieranweisungen im Formatstring für das Auszugebende gibt. Das sind alle "eingebauten" Datentypen. Eine struct besteht ja aus Membern, die letztendlich alle von einem der eingebauten Basistypen sind. Und: Mit printf erzeugt man immer eine Textausgabe. > Ich habe eine struct definiert (im RAM) und möchte die quasi als > memory-Dump ausgeben. Das ist aber etwas ganz anderes und hat mit Textausgabe nichts mehr zu tun. > Also aus einem (char)0 soll auch das > nichtdruckbare Zeichen werden, nicht '0'. Du brauchst erst mal eine Basisfunktion, die dir ein einzelnes Byte rausgibt. Wie diese Funktion aussieht hängt von deiner Umgebung ab. putchar ist schon mal ein guter Ansatzpunkt Und dann brauchst du noch eine Funktion, die einen Speicherbereich sukzessive an putchar verfüttert
1 | void putmem( void* memory, size_t size ) |
2 | {
|
3 | uint8_t memAsByte = (uint8_t) memory; |
4 | size_t i; |
5 | |
6 | for( i = 0; i < size; ++i ) |
7 | putchar( *memAsByte ++ ); |
8 | }
|
Damit hast du schon alle Bestandteile zusammen. Du musst nur noch eine Variable an putmem 'verfüttern'.
1 | struct irgendwas myVar; |
2 | |
3 | ..
|
4 | |
5 | putmem( myVar, sizeof( myVar ) ); |
Einen Pointer auf den Struct in einen Pointer auf char casten, und dann Zeichen für Zeichen per putc ausgeben. Oliver
> Quasi etwas wie WriteFile(hFile, &struct, sizeof(struct), ...);
fwrite(&struct, sizeof(struct), 1, stdout);
Hallo Leute, erst einmal herzlichen Dank für die vielen Antworten! Das ganze als lesbaren String auszugeben war nicht Sinn der Sache. Momentan arbeite ich in einem (leider fremden) Programm an einer kleinen Erweiterung, mit der ich ein struct an eine andere Maschine übergeben möchte. Eigentlich ganz simpel. Da die zugehörige Schnittstelle sowieso auf stdout abgebildet wird und es im bisherigen Prog keine WriteBuffer()-Funktion o.ä. gibt, war printf mein erster Ansatz. Hatte da das Windows WriteFile() im Hinterkopf. Daher kommt mir der Vorschlag mit fwrite() am nächsten. Daß ich da nicht selbst drauf gekommen bin... ts ts (Naja, normalerweise meide ich die IO-Streams...) Nochmals Danke an alle & einen schönen Abend! Andy
Andy schrieb: > Das ganze als lesbaren String auszugeben war nicht Sinn der Sache. > Momentan arbeite ich in einem (leider fremden) Programm an einer kleinen > Erweiterung, mit der ich ein struct an eine andere Maschine übergeben > möchte. Eigentlich ganz simpel. Es ist nicht wirklich empfehlenswert, structs einfach so wie sie im Speicher stehen an eine andere Maschine zu senden, denn das funktioniert nur solange die beiden Maschinen die gleiche (oder eine halbwegs ähnliche) Architektur haben. Sobald die beiden Maschinen sich zu sehr unterscheiden (Byte Order, Wortbreite z.B., aber ggf. sogar schon bei unterschiedlichen Compileroptionen!), kann das Speicherlayout der struct sich unterscheiden, auch wenn beide Male derselbe Sourcecode kompiliert wird, und dann funktioniert die Kommunikation nicht mehr. Besser ist es, die Felder einzeln der Reihe nach in definierter Form zu übertragen, also mit definierter Bitbreite, Byte-Reihenfolge etc. Das kann ruhig in binärer Form geschehen, nur eben in einer einheitlichen, architekturunabhängigen Form. Damit gibt es dann auch in der Zukunft, bei Rechnerupgrades, neuen Compilerversionen etc. keine Probleme. Aufgrund dieser Problematik gibt es überhaupt Begriffe wie "Network Byte Order" und "Host Byte Order", und stellt z.B. das Unix-Socket-API Funktionen wie htonl() und ntohl() zur Verfügung, die zwischen den beiden umwandeln. Andreas
wie schon erwähnt, memory aligning/padding durch den compiler und byte order (Big Endianvs. little endian) durch den verwendeten uC/uP können zum fallstrick werden, wenn man solch eine struktur zur Kommunikation verwenden möchte und die einfach byteweise übermittelt... Abhilfe wäre z.B mit sprintf() die einzelnen Elemente formatiert in einen string ausgeben, den übermitteln und auf der rx-seite per sscanf() mit gleicher formatierung wieder in Strukturelemente holen. Allerdings fressen die lib-funktionen der printf und scanf familie gerne laufzeit und code... Es hilft nur ein klar definiertes telegrammformat als robuster und sicherer ansatz... gruss, tom.
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.