www.mikrocontroller.net

Forum: Compiler & IDEs Basic c-frage: const char - Parameterübergabe?


Autor: sverige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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_fu...

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.

Autor: Thomas Pircher (tpircher) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
#define Debug_MSG(s) Debug_MSG_Function(s, sizeof(s))
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
char *str = "hallo, das ist ein Debugstring"
Debug_MSG(str)

Denn sizeof(str) == sizeof(char *) == 2 oder 4 oder sonstwas, je nach 
Architektur.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
void uart_puts( const char* str )
{
  while( *str )
    uart_putc( *str++ );
}

(uart_putc ist die Basisfunktion, die 1 Zeichen ausgeben kann. 
uart_puts ist die Erweiterung um einen kompletten String auszugeben)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.