Basic c-frage: const char - Parameterübergabe?

Gast #1154585
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
#1154606
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.
#1154614
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.
Persönliche Seite #1154615
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.
#1154635
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)

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.