Hallo, Ich versuche gerade mir eine Debug-Routine zu schreiben die mir Zeichenketten über die Uart anzeigt. Ich habe dazu einen Uart treiber der eigentlich nur ein char array und die Länge davon braucht um das zu tun. Jetzt bin ich gerade dabei mir das Unterprogramm Debug_MSG(const char buffer[]); zu schreiben welches ich dann so aufrufen möchte: Debug_MSG("Hello World"); Dass soll dan weiters den Uart treiber aufrufen und eben ein Hello World ausgeben. Das funktioniert natürlch so einfach nicht, weil ich ja beim Aufrug des Unterprogramms die Information über die Länge des Strings verloren habe und somit nicht an den treiber weitergeben kann. Die Alternativen: Debug_MSG("Hello World", 11); //(Länge des Strings mitgeben) Debug_MSG("Hello World\0"); //(String dann auf \0 parsen) finde ich unschön. Gibt es nicht irgendeinen Trick wie ich den const char[] an ein Unterprogramm weitergebe und dabei nicht durch die Pointer conversion die Länge des Strings verliere?? Extra jedes Mal eine Variable die dann den String enthält und global ist, bzw in ein struct verpackt möchte ich aben auch nicht. Vielleicht irgendwie mit Macros? Das ganze klingt natürlich etwas kleinlich, aber wenn ich dafür eine geschickte Lösung finden würde, könnte ich die öfters einsetzen. Also danke für Tipps! lg
Strings sind in C grundsätzlich automatisch nullterminiert! "Hello
World" ist nicht 11, sondern 12 Zeichen lang, weil Du den Nullterminator
am Ende vergessen hast.
Praktisch alle Funktionen in C, die sich mit der Auswertung und
Verarbeitung von Strings befassen, werten den Nullterminator aus, so
dass eine Übergabe der Stringlänge gar nicht erforderlich ist. Ein '\0'
ist für eine solche Funktion das Zeichen, dass der String hier endet.
> Debug_MSG("Hello World\0"); //(String dann auf \0 parsen)
Der zusätzliche Nullterminator ist überflüssig. Und genau das auf '\0'
parsen machen o.g. Funktionen, und das solltest auch Du machen.
sverige wrote: > Also danke für Tipps! Der beste Tip ist immer noch: Kauf dir ein C-Buch. String Verarbeitung ist in C etwas essentielles. Ohne Literatur fällt man da ganz schnell auf die Schnauze. Eine klitzekleine Einführung in die Stringverarbeitung mit den wichtigsten Stolpersteinen findest du hier: http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F Aber das ist kein Ersatz für Literatur! > Debug_MSG("Hello World\0"); //(String dann auf \0 parsen) Siehst du, das mein ich mit Grundlagen. Auch konstante Strings sind per Definition immer automatisch mit einem \0 Zeichen abgeschlossen. Dafür sorgt der Compiler.
1 | Debug_MSG("Hello World\0"); //(String dann auf \0 parsen) |
ist unnoetig, da C den String automatisch mit '\0' abschliesst. Das duerfte die sicherste Methode sein, wenn du unbedingt nur einen Parameter uebergeben willst. Allerdings musst du dann in det Bebug_MSG() Funktion die Position des Stringterminators wieder ermitteln. Eine andere (fehlertraechtige) Metode ist mit Makros:
1 | #define Debug_MSG(s) Debug_MSG_Function(s, sizeof(s))
|
2 | void Debug_MSG_Function(const char *str, size_t str_len); |
Das funktioniert gut mit konstanten Strings, aber ein Code wie der folgende wird nicht mehr funktionieren
1 | char *str = "hallo, das ist ein Debugstring" |
2 | Debug_MSG(str) |
Denn sizeof(str) == sizeof(char *) == 2 oder 4 oder sonstwas, je nach Architektur.
Thomas Pircher wrote: > Allerdings musst du dann in det Bebug_MSG() Funktion die Position des > Stringterminators wieder ermitteln. Äh, nein. Musst du nicht. Er fällt automatisch drüber, wenn er in einer Schleife die einzelnen Zeichen abarbeitet. Sein Problem ist an dieser Stelle eigentlich nicht die Debug_MSG Funktion, sondern der UART-Treiber. Was er braucht ist eine uart Funktion die einen String ausgeben kann und nicht nur ein allgemeines char-Array (wofür er die Längenangabe tatsächlich brauchen würde). Bei einer String-Ausgabe jedoch, taucht die tatsächliche Stringlänge meistens nirgends explizit auf. An dieser Stelle wäre alles andere (mittels Länge zu operieren) lediglich Murks. Vor allem, weil eine Stringausgabe nun wirklich kein Problem darstellt
1 | void uart_puts( const char* str ) |
2 | {
|
3 | while( *str ) |
4 | uart_putc( *str++ ); |
5 | }
|
(uart_putc ist die Basisfunktion, die 1 Zeichen ausgeben kann. uart_puts ist die Erweiterung um einen kompletten String auszugeben)
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.