Hallo, ich möchte eine Reihe AT Befehle in Arrays ablegen. Wenn ich einfach char Befehl[] = {"AT+"}; schreibe, erhalte ich im Array 'A','T','+','NULL' also 4 Bytes. Die "NULL" stört, weil ja der eigentliche Befehl noch nachfolgend geschickt wird. Wie kann ich also mit der geringsten Schreibarbeit verhindern, dass die 'NULL' am Ende mit im Array abgelegt wird? Funktioniert dieses Vorhaben, wenn ich einfach: char Befehl[3] = {"AT+"}; definiere und somit den Platz im Array auf meine drei Wunsch-Bytes reduziere?
Array schrieb: > Die "NULL" stört, weil ja der eigentliche Befehl noch nachfolgend > geschickt wird. dann stört sie aber nicht, denn sie wird nicht versendet. Sonst musst du dir ja wieder etwas einfallen lassen, damit du die länge der Daten kennst.
nun, ich lege meine Arrays mit vordefinierten Kommandos ja alle in den Speicher ab. Erstens möchte ich nicht, dass bei jedem Befehl in jedem Array diese NULL mit gespeichert wird. Zweitens möchte ich nicht, dass sie versendet wird, weil mein Funkmodul dies ja wieder nicht verstehen würde. Also möchte ich sie gar nicht erst irgendwo mit ablegen.
Array schrieb: > Funktioniert dieses Vorhaben, wenn ich einfach: > char Befehl[3] = {"AT+"}; > > definiere und somit den Platz im Array auf meine drei Wunsch-Bytes > reduziere? Nein, dann wird die 0 dahinter geschrieben und zerstört das folgende Byte. Außerdem gibt es Mecker vom Compiler. Die 0 ist die Terminierung eines Strings in C. Wenn du das verhindern willst, mußt du dir eine andere Programmiersprache suchen.
Array schrieb: > Zweitens möchte ich nicht, dass sie versendet wird, weil mein Funkmodul > dies ja wieder nicht verstehen würde. Das tut man gewöhnlich auch nicht.
Thomas E. schrieb: > Nein, dann wird die 0 dahinter geschrieben und zerstört das folgende > Byte. nein > Außerdem gibt es Mecker vom Compiler. nein
Array schrieb: > Zweitens möchte ich nicht, dass sie versendet wird, weil mein Funkmodul > dies ja wieder nicht verstehen würde. sie wird doch gar nicht gesendet. Bei String-Funktionen werden alle Zeichen bis zur NULL verarbeitet aber nicht die NULL selber. Wenn du printf verwendest, wird auch keine NULL ausgegeben, obwohl sie enthalten ist.
Allenfalls muss man mit einer eigenen String Klasse arbeiten, die ohne Null arbeitet.
Ja, die NULL terminiert einen String. Mein Funkmodul mit AT-Kommandos will aber keine NULL haben, sondern genau "AT+KOMMANDO\r" Der Befehl "AT+KOMMANDO\NULL\r" würde ja schon wieder nicht verstanden werden.
Array schrieb: > Erstens möchte ich nicht, dass bei jedem Befehl in jedem Array diese > NULL mit gespeichert wird. Das ist aber bei Strings in C so üblich. > Zweitens möchte ich nicht, dass sie versendet wird, weil mein Funkmodul > dies ja wieder nicht verstehen würde. Warum sollte die NUL mitversendet werden ? Das passiert doch nur, wenn du etwas falsch programmierst. Ein fputs(Befehl,f) ein write(f,Befehl,strlen(Befehl)); sendet auch keine NUL mit nur ein fwrite(f,sizeof(Befehl),1,Befehl); würde sie mitsenden, dann hat du eben falsches programmiert. > Funktioniert dieses Vorhaben, wenn ich einfach: > char Befehl[3] = {"AT+"}; Nein, bitte lese ein Grundlagenbuch zu C.
Array schrieb: > Der Befehl "AT+KOMMANDO\NULL\r" würde ja schon wieder nicht verstanden > werden. die null wird nicht gesendet! Wie sendest du denn deine Daten?
Array schrieb: > Erstens möchte ich nicht, dass bei jedem Befehl in jedem Array diese > NULL mit gespeichert wird. > Zweitens möchte ich nicht, dass sie versendet wird, weil mein Funkmodul > dies ja wieder nicht verstehen würde. > Also möchte ich sie gar nicht erst irgendwo mit ablegen. Ein String endet immer mit NULL, gleichzeitig dient diese NULL als Längenangabe des Strings. Die C-Stringfunktionen "leben" davon. Wenn Du also zum Versenden Stringfunktionen verwendet ist das so genau richtig, und die NULL wird nicht mit versendet. Wenn Du die NULL nicht haben willst: wie erkennst Du dann die Länge des AT-Befehls? Oder verwendest Du (zufällig) nur 3-Byte-Befehle?
Wird die NULL bei einer "normalen" Uart-Verbindung tatsächlich nicht gesendet, auch dann nicht wenn sie Bestandteil des Stringarrays ist, welches man an die Funktion übergibt?
Michael B. schrieb: >> Funktioniert dieses Vorhaben, wenn ich einfach: >> char Befehl[3] = {"AT+"}; > > Nein, bitte lese ein Grundlagenbuch zu C. oder du. Das ist schon so ok.
Array schrieb: > Wird die NULL bei einer "normalen" Uart-Verbindung tatsächlich nicht > gesendet, auch dann nicht wenn sie Bestandteil des Stringarrays ist, > welches man an die Funktion übergibt? wenn man die richtigen Funktionen verwendet: ja
Kleine Pingeligkeit: NULL ist ein Makro für Null-*Pointer*. Die 0 im letzten char ist eine "echte" 0, d.h. der Integer-Wert 0 (kein Pointer!). Daher ist es etwas ungeschickt, hier NULL zu schreiben. Würde man im Code hier explizit NULL verwenden, können sich u.U. auch Probleme ergeben.
Array schrieb: > Wird die NULL bei einer "normalen" Uart-Verbindung tatsächlich nicht > gesendet, auch dann nicht wenn sie Bestandteil des Stringarrays ist, > welches man an die Funktion übergibt? da niemand hier wissen kann, welche Funktionen du zum Senden benutzt, ist eine sinnvolle Antwort eigentlich nicht möglich...
Array schrieb: > Funktioniert dieses Vorhaben, wenn ich einfach: > char Befehl[3] = {"AT+"}; Ja, das ist erlaubt. Bloß wie soll dann die Senderoutine hellsehen, daß es sie 3 Bytes senden soll? Die '/0' als Endekennzeichen hat man sich nämlich nicht aus Jux und Dollerei ausgedacht.
Array schrieb: > char Befehl[] = {"AT+"}; Das ist ziemlich unsinnig. Ein Array, welches kein weiteres Zeichen aufnehmen kann, und (vermutlich) auch nicht modifiziert werden soll, braucht überhaupt nicht im RAM zu liegen, sondern belegt nur Platz. Welchen µC nutzt Du? Zeig doch mal die Verwendung von Befehl[]. Das kann man bestimmt auch anders schreiben... Array schrieb: > Funktioniert dieses Vorhaben, wenn ich einfach: > char Befehl[3] = {"AT+"}; Ja, das funktioniert und es gibt auch keinen Mecker vom Compiler, weil das in C ausdrücklich so definiert ist, dass in diesem speziellen Fall (Größe des Arrays == Länge des Strings) das Speichern des NUL-Bytes (Ja, es heisst NUL mit einem L bzw. '\0' und nicht NULL) unterbleibt. Aber dann kommt es stark darauf an, was Du mit Befehl[] macht. strcpy() und Co. sind dann jedenfalls nicht mehr anwendbar. Befehl[] ist dann nur noch ein Array und kein C-String mehr. Also: Zeig bitte die Verwendung. Darauf kommt es an.
Array schrieb: > Hallo, > > ich möchte eine Reihe AT Befehle in Arrays ablegen. > > Wenn ich einfach > > char Befehl[] = {"AT+"}; > > schreibe, erhalte ich im Array > 'A','T','+','NULL' > > also 4 Bytes. nicht 'NULL', sondern '\0'. Mit NULL hat das überhaupt nichts zu tun. > Funktioniert dieses Vorhaben, wenn ich einfach: > char Befehl[3] = {"AT+"}; > > definiere und somit den Platz im Array auf meine drei Wunsch-Bytes > reduziere? Ja, das geht in C (nicht allerdings in C++). Du kannst dann aber keine Standard-String-Funktionen mehr nutzen, weil die auf die 0 am Ende angewiesen sind, um die Länge zu ermitteln. Du musst also alles mit eigenen Funktionen machen und dir die Länge irgendwie separat merken. Array schrieb: > Ja, die NULL terminiert einen String. Ja, genau. Das heißt, es wird alles vor der 0 als Teil des Stringinhalts verarbeitet, die 0 aber nicht. Sie ist nur der Marker, dass der eigentliche Inhalt bis ein Zeichen vor der 0 geht. Array schrieb: > Wird die NULL bei einer "normalen" Uart-Verbindung tatsächlich nicht > gesendet, auch dann nicht wenn sie Bestandteil des Stringarrays ist, > welches man an die Funktion übergibt? Das hängt von deiner Funktion ab, aber wenn das eine ist, die für Stringhandling ausgelegt ist, dann schickt das \0 nicht mit. Wenn nicht, musst du aber eh irgendwo explizit die Länge des Arrays angeben. Dann kannst du auch einfach die Länge ohne das \0 angeben. Dafür ist das \0 ja da: Damit die Stringfunktionen wissen, wo der String zu ende ist. Lässt du das weg, können sie die Länge nicht mehr daraus ermitteln. Michael B. schrieb: >> Funktioniert dieses Vorhaben, wenn ich einfach: >> char Befehl[3] = {"AT+"}; > > Nein, bitte lese ein Grundlagenbuch zu C. Wer so rumtönt, sollte sich erstmal selbst mit den Grundlagen beschäftigen.
1 | char Befehl[3] = {"AT+"}; |
macht genau das, was er sich vorstellt. Es ergibt einen String ohne das abschließende \0.
Oh D. schrieb: > Allenfalls muss man mit einer eigenen String Klasse arbeiten, die ohne > Null arbeitet. Und welchen Vorteil hätte die? Das Ende bzw. die Länge von Strings müsste sie sich auch irgendwie merken. Speicherplatz spart das nicht.
so würde ich das aufbauen: char AT_Command[]={"AT+"}; char AT_Restart[]={"RST"}; ... weitere AT-Befehle. Das eigentliche Modul möchte "AT+RST" empfangen.
Array schrieb: > Das eigentliche Modul möchte "AT+RST" empfangen. Dann zeig endlich den Aufruf, wie Du das dem Modul sendest! Denn damit ist es noch lange nicht getan. Da fehlt mindestens ein '\r'.
> Und welchen Vorteil hätte die? Das Ende bzw. die Länge von Strings
müsste sie sich auch irgendwie merken. Speicherplatz spart das nicht.
Eine eigene Stringklasse mit der Laenge separat duerfte dann die Null
als gueltigen Character enthalten, auch mehrfach.
Ja, manche moegen das Missbrauch nennen und auf andere Strukturen
verweisen. Dann nennt man's eben anders.
Oh D. schrieb: > Eine eigene Stringklasse mit der Laenge separat duerfte dann die Null > als gueltigen Character enthalten, auch mehrfach. Dürfte sie, aber ... wozu braucht man das? Wenn man es einfach Bytearray nennt ... ist's weder was neues noch was verwirrendes. Um aber einem Modem AT-Kommandos zu senden, ist die Idee reichlich bizarr, hier auf Strings zu verzichten.
Array schrieb: > so würde ich das aufbauen: > char AT_Command[]={"AT+"}; > char AT_Restart[]={"RST"}; > ... weitere AT-Befehle. > > > Das eigentliche Modul möchte "AT+RST" empfangen. Du kannst da sogar zwei Aufrufe zum Senden machen. Du musst nicht erst einen neuen String zusammen basteln.
Peter II schrieb: > Wie sendest du denn deine Daten? Justus S. schrieb: > da niemand hier wissen kann, welche Funktionen du zum Senden benutzt, > ist eine sinnvolle Antwort eigentlich nicht möglich... Frank M. schrieb: > Also: Zeig bitte die Verwendung. Darauf kommt es an. Frank M. schrieb: > Dann zeig endlich den Aufruf, wie Du das dem Modul sendest! Bis dahin ist eine weitere Diskussion wohl überflüssig ...
@A-rray Die str-Befehle basieren auf 0-Terminierten Zeichenketten. Das ist sozusagen "eingebaut". Der Befehl strcat () z.B., kopiert alles EXCLUSIVE" der angehängten Null. Hängt aber die Null, zur weiteren Verwendung, hinten an. Der Glaube, das Weglassen der angehängten Null, würde Platz sparen, ist ebenfalls Unsinn. "Zeichenkette Eins" und "Zeichenkette Sieben" benötigen für jede Ausgabe oder Bearbeitung eine Längenkonstante. Also die Konstanten 17 und 19. Oder einen Algorithmus, der alles bis zur angehängten Null ausgibt. Ersparnis = Null; Fehlerwahrscheinlichkeit maximal. Darüber hinaus haust Du Dir die Finger wund, wenn Du statt: "Zeichenkette Eins" 'Z','e','i','c','h','e','n','k','e','t','t','e',' ','E','i','n','s'; als normal ansiehst. Und die Länge überall mit mitschleppst. Also, was Du vorhast geht, ist aber schlicht und einfach Krampf. Und wie auch meine Vorgänger bereits gefragt haben: Was soll das Ganze?
Array schrieb: > so würde ich das aufbauen: > char AT_Command[]={"AT+"}; > char AT_Restart[]={"RST"}; > ... weitere AT-Befehle. > > > Das eigentliche Modul möchte "AT+RST" empfangen. mmm., vielleicht lieber so:
1 | const char * const AT_Command="AT+"; |
2 | const char * const AT_Restart="RST"; |
3 | |
4 | void sendCommand(const char *p1, const char *p2, const char *p3) |
5 | {
|
6 | if(p1) {while(*p1) {SendByte(*p1++);}} |
7 | if(p2) {while(*p2) {SendByte(*p2++);}} |
8 | if(p3) {while(*p3) {SendByte(*p3++);}} |
9 | }
|
10 | |
11 | ...
|
12 | sendCommand(AT_Command, AT_Restart, 0); |
kein schöner Code, sicher voller Schreibfehler, aber ein Beispiel für 0-Terminierung und damit Du beschreiben kannst, was Du eigentlich möchtest. Die je 2 const zeigen übrigens (wie von anderen angemerkt) dass hier garkein RAM belegt werden braucht.
...ok, danke für die vielen Antworten. Werde also erstmal die vorgegebene \0 verwenden. Macht viele gegebene Funktionen besser verwendbar. Eine Frage noch: char Array[]={"x"} Wenn ich die Funktion sizeof(Array) verwende, dann müsste sie mir als Ergebnis "2" zurückgeben, richtig?
Das ist richtig. Für strings gibt's aber strlen. Das gibt korrekt 1 zurück
Array schrieb: > char Array[]={"x"} > Wenn ich die Funktion sizeof(Array) verwende, dann müsste sie mir als > Ergebnis "2" zurückgeben, richtig? Nein, sie gibt 2 (ohne ") zurück.
Array schrieb: > Wenn ich die Funktion sizeof(Array) verwende, dann müsste sie mir als > Ergebnis "2" zurückgeben, richtig? Wobei es Du sizeof oder strlen meist nicht brauchst. Bei Strings oder Streams ist ein for i oder ein memcpy selten sinnvoll.
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.