Hallo Ihr,
ich habe in einer UART-Funktion einen Punkt, welcher mir das aktuell
anstehende Zeichen liefert und in einen Buffer schreibt.
Dieser Buffer ist so definiert uart0_command_buffer[6];
Jetzt hab ich noch einen Counter, welcher immer nach reinschreiben
inkrementiert wird.
Dieser gibt sozusagen immer an, welche stelle als nächstes beschrieben
wird, ist dieser aber == 5, wird das Ende des Strings geschrieben.
Nach dieser Funktion werte ich im Hauptprogramm den String aus. Es
klappt alles perfekt.
Danach lösche ich den String, bzw setze den gesamten Inhalt auf NULL.
Nur wie mache ich das ganz genau?!
Ich habe derzit:
1
// String wieder komplett entleeren
2
uart0_command_buffer[0]=0;
3
uart0_command_buffer[1]=0;
4
uart0_command_buffer[2]=0;
5
uart0_command_buffer[3]=0;
6
uart0_command_buffer[4]=0;
7
uart0_command_buffer[5]=0;
8
uart0_command_buffer[6]=0;
Der Compiler bringt mir aber eine Meldung, dass ich über den Bereich des
Arrays bin.
Wie leere ich den String perfekt?!
Hoffe jemand kann mir genauer helfen.
Klar... Du hast als Buffer ein Array mit 6 Elementen definiert. Und
schreiben willst Du in Elemet [0] bis einschließlich Element [6]. Das
sind zusammen 7 Elemente.
Ich würde es so machen:
for (i=0; i<6; i++)
uart0_command_buffer[i] = 0;
Liest sich leichter und wird vom Compiler eh anhand seiner Regeln
entweder schnell oder klein optimiert.
Okay,
danke schonmal, was genau macht die Funktion memset(); ??
Und, wenn ich jetzt unsigned char XXX[6]; schreibe definiere ich ein
Array mit 6 Einträgen, also 0-5 oder?
Und das Ende des Strings schreib ich ja als XXX[Y] = '\0'
Ist das dann ein Zeichen? Eigentlich dann ja schon oder?
Danke nochmal!
Problemmensch schrieb:> danke schonmal, was genau macht die Funktion memset(); ??
google: man memset
> Und, wenn ich jetzt unsigned char XXX[6]; schreibe definiere ich ein> Array mit 6 Einträgen, also 0-5 oder?
ja
> Und das Ende des Strings schreib ich ja als XXX[Y] = '\0'> Ist das dann ein Zeichen? Eigentlich dann ja schon oder?
ja, ist noch eines, es braucht auch seinen Platz. Es kennzeichnet in C
das Ende eines Strings.
Okay, also ist es genau EIN Zeichen. Also 5 Zeichen + das Ende des
Strings = 6, also unsigned char XXX[6].
Wie sieht das Ende eines Strings aus? Ich schreibe ein \0 rein, aber was
ist an der Stele vom System überhaupt drin?
Ich habe da irgendwie ein kleines Verständnisproblem -.-
Es ist ein Byte, bei dem alle Bits 0 sind. Dieser Sonderfall ist dafür
reserviert, das Ende des Strings zu kennzeichnen.
Du kannst auch foo[6] = 0; schreiben.
Problemmensch schrieb:> danke schonmal, was genau macht die Funktion memset(); ??
An einigen ganz wenigen ausgesuchten Stellen im Internet und
in der Doku deines Systems ist memset() möglicherweise dokumentiert.
> Und, wenn ich jetzt unsigned char XXX[6]; schreibe definiere ich ein> Array mit 6 Einträgen, also 0-5 oder?
Genau.
>> Und das Ende des Strings schreib ich ja als XXX[Y] = '\0'> Ist das dann ein Zeichen? Eigentlich dann ja schon oder?
Ja.
Problemmensch schrieb:> Wie sieht das Ende eines Strings aus? Ich schreibe ein \0 rein, aber was> ist an der Stele vom System überhaupt drin?
Vorher? Je nachdem, was halt vorher mit dem Speicher passierte
bzw. wofür er vorher verwendet wurde.
Danahc natürlich die 0.
> Ich habe da irgendwie ein kleines Verständnisproblem -.-
Es gibt Bücher, in denen die Merkwürdigeiten von C mehr oder
weniger gut beschrieben sind :-)
In diesem Fall aber foo[5] = 0; denn das Array hat nur sechs Elemente
(inklusive der Null!). Daher ist [6] schon außerhalb des Arrays. Das hat
nichts mit der Null zu tun.
hubert schrieb:> Du kannst auch foo[6] = 0; schreiben.
Nico Sch. schrieb:> In diesem Fall aber foo[5] = 0; denn das Array hat nur sechs Elemente>> (inklusive der Null!). Daher ist [6] schon außerhalb des Arrays. Das hat>> nichts mit der Null zu tun.>>>> hubert schrieb:>>> Du kannst auch foo[6] = 0; schreiben.
Stinmmt. Jetzt bin ich in die gleiche Falle getappt... :-S
Wenn es aber doch der Wunsch nach "vollständigem Entleeren" ist: Den
'sizeof'-Operator nehmen! Dann ist man unabhängig von der Größe - hat
diese nur an einer Stelle definiert - oder alternativ für die Größe ein
#define nehmen. Wenn man viele verschieden große Arrays hat, ist
'sizeof' schon übersichtlicher.
Entweder:
(Das Teilen durch die Größe eines Einzelelements kann man sich bei
'char' allerdings sparen. Gehört der Vollständigkeit halber aber dazu.)
Oder (Einzelelementgröße egal):
1
unsignedcharuart0_command_buffer[6];// egal, wie groß ...
hubert schrieb:> Es ist ein Byte, bei dem alle Bits 0 sind. Dieser Sonderfall ist dafür> reserviert, das Ende des Strings zu kennzeichnen.
Diese grundsätzliche Aussage finde ich immer verwirrend und
möglicherweise ist das auch der Grund für die Verwirrung des OP.
Es ist Konvertion, daß die üblichen String-Funktionen (z.B. strcpy) auf
das 0 als Markierung für das Ende des Strings reagieren und daß, wenn
man "bla" schreibt, anschließend b l a \0 im Speicher steht, aber C
hindert niemanden daran, über ein \0 hinweg zu lesen oder zu schreiben.
Es wird auch nicht etwa implizit Platz dafür reserviert oder ähnliches.
Alles hinter dem Null-Byte gehört nicht mehr zum String.
Es reicht also völlig, nur das erste Byte mit 0 zu beschreiben.
Oftmals braucht man einen String aber nicht zu leeren.
Du empfängst bis zum Endezeichen, ersetzt es mit 0 und erst dann wird
der String ausgewertet. Es ist ja unsinnig, einen String auszuwerten,
wenn er noch nicht alle Zeichen enthält.
Peter
Klaus Wachtler schrieb:> Noch netter wäre ein const size_t statt #define, aber sonst ACK.
Warum? Eine Elementanzahl ist eher noch 'int' als 'size_t' (meistens
ohnehin aufgelöst als 'unsigned int') oder einfach nur eine Zahl. Oder
soll ich die Array[byte]größe damit festlegen und die Elementeanzahl
wiederum ausrechnen?
df1as schrieb:> Klaus Wachtler schrieb:>> Noch netter wäre ein const size_t statt #define, aber sonst ACK.>> Warum?
Weil du #define vermeiden möchtest.
Ein #define wird vom Preäprozessor aufgelöst. Ein size_t ist aber in den
Debug Symboltabellen immer noch vorhanden, da es eine Variable ist.
> Eine Elementanzahl ist eher noch 'int' als 'size_t' (meistens> ohnehin aufgelöst als 'unsigned int')
meistens. Aber nicht immer.
Mit einem size_t musst du dir darüber aber keine Gedanken machen.
> soll ich die Array[byte]größe damit festlegen und die Elementeanzahl> wiederum ausrechnen?
Das ist quatsch.
Denn bei der Definition eines Arrays gibt man immer die Anzahl Elemente
an.
Anders rum wird ein Schuh daraus:
Hat man ein Array, welches durch die Initialisierung automatisch vom
Compiler dimensioniert wird, dann benutzt man ein sizeof Konstrukt um
die tatsächliche Arraydimensionierung festzustellen.