Hallo ! Ich bin mir nicht 100% sicher, wie ich eine Rückgabe meiner Funktion richtig programmiere. Deswegen brauch ich mal schnell und kurz eure Hilfe. // Lesen eines Filediskriptors int auslesen( char ARRAY[256], int len ) { read(fd,ARRAY,256); // Abfrage Serielle Schnittstelle len = strlen(ARRAY); // Abfrage Länge des ARRAY } // Im Hauptprogramm möchte ich gerne BUFFER bzw. den Inhalt und den len weiter nutzen. int main() { ... auslesen(BUFFER); ... } Wie muss "int auslesen" richtig programmieren, sodaß ich den Inhalt verwerten kann ?? Oder ist das so richtig ?? Vielen Dank !!
hallo, annahme: du hast den fildescriptor fd global definiert (und geholt) dann sollte read so funktionieren, obwohl ich das mit pointer ja lieber mag .. aber das thema gabs ja neulich schon. und du solltest das "len" zurückliefern: return len; dein compiler hat sich sicherlich schon über den fehlenden return-wert beschwert. bye kosmo
Wie keine Pointer oder Adresszeiger ? Einfach das return noch mit einfügen und dann ist gut ? int auslesen( char ARRAY[256], int len ) { read(fd,ARRAY,256); // Abfrage Serielle Schnittstelle len = strlen(ARRAY); // Abfrage Länge des ARRAY return len; }
literatur ist sicher eine gute idee, aber wenn's mal wieder eilig ist, braucht auch niemand den oberlehrer auspacken. scnr. und dies noch zum feierabend: im beispielcode bleibt noch ungeklärt, wie der filedescriptor in der main deklariert, aber in der anderen routine benutzt werden soll.
Außerdem hat Angela Merkel nicht verstanden, dass man natürlich einen Array-Parameter deklarieren kann, wenngleich die Angabe der Array- Größe dort witzlos ist. Weiterhin hat sie zwar die sinnlose Deklaration von len als Funktionsparameter eliminiert (wird dann sowieso nur als lokale Variable missbraucht, da kann man auch gleich eine lokale Variable definieren), aber dafür gleich gar keine Definition von len mehr in auslesen() übrig gelassen. So richtig hat sie sich die Bücher wohl auch nicht angeguckt... An den OP: bist du dir sicher, dass strlen() das richtige ist, d.h. dass du nach dem Versuch, 256 Bytes zu lesen, einen String bekommst, der am Ende mit Nullbytes gefüllt wird? Oder willst du vielmehr wissen, wie viele Bytes von read() überhaupt gelesen werden konnten? Dafür braucht's kein strlen(), sondern diese Anzahl gibt read() selbst zurück. Um aber richtig helfen zu können, musst du mehr über deine Umgebung (ist das ein Unix-Umfeld?) sowie über deine Daten (Texte, Binärdaten) sowie Datenquelle (Terminal, Datei) schreiben.
> Dafür braucht's kein strlen()
Genauer gesagt: Da funktioniert strlen() gar nicht. Selbst wenn die
gelesenen Daten mit einem \0-Zeichen terminiert wären, sollte man sich
nicht darauf verlassen. Bei einem Übertragungsfehler wird das vielleicht
mal verschluckt, und schon schmiert einem gleich der µC ab.
Das ist aber nicht die liebevolle Art, für die sich Angela Merkel sonst rühmt. Jörg und Rolf haben schon recht, die read() Funktion schließt das Feld niemals mit '\0' ab, wenn man die Daten mit den Stringfunktionen weiterverarbeiten will dann sollte man ganz explizit ans Ende einen Null-Character schreiben. len = read(fd, array, LEN-1); array[len] = '\0'; Klaus
> Wo habt ihr nur alle eure Glaskugeln her?
Ollivanders Zauberladen, Winkelgasse, natürlich !
> Wenn Stefan die Länge des Arrays mittels strlen bestimmen will, muss er > die eingelesenen Daten so angelegt haben, dass das letzte eingelesene > Zeichen '\0' ist. Dann braucht man nix Nullen anhängen. Dafür muß man vor jedem Aufruf der Funktion das komlette Array ausnullen, und das nur, damit strlen nochmal unnötig durchiterieren kann. Das wäre zumindest nicht besonders zweckmäßig. Außerdem gehen Daten verloren, wenn in den empfangenen Bytes ein Nullbyte ist.
Hallo erstmal und Danke für Eure Beiträge, besonders die mit der Glaskugel ;-) Nun, aber mal wieder zurük zur meiner Frage. Im wesentlichen wollte ich einen Funktionsaufruf haben, der mir den Inhalt meines ARRAY und die Lange des ARRAY wieder gibt. auslesen(BUFFER,len); oder len = auslesen(BUFFER); habe ich in meinem Programm übernommen. Ein weiteres ist, da ich einen Ringpuffer auslesen muss, die Funktion an mehren Stellen in meinem Hauptprogramm aufzurufen. Nun,angenommen der Ringpuffer beinhaltet 100Bytes an Daten. Jetzt möchte ich diese Daten auswerten. Wie würdet Ihr dies anstellen. Die Nutzdaten sind unterschiedliche Länge und wie filter ich die Nutzdaten heraus? Soll man den ganz Puffer auslesen, und mit einen strcmp() vergleichen? Aber selbst dann stehen die Nutzdaten, quasi hintereinander LAMPEPUMPETESTSTOPSTART so stehen die Nutzdaten im Ringpuffer, wie soll man damit klar kommen ??? Oder soll explizit beim schreiben eine Terminierung stattfinden LAMPE0PUMPE0TEST0STOP0.... etc... MFG Stefan
hallo, nun, um eine terminierung kommst du nicht so einfach herum. >Nun,angenommen der Ringpuffer beinhaltet 100Bytes an Daten. Jetzt möchte >ich diese Daten auswerten. Wie würdet Ihr dies anstellen. Die Nutzdaten >sind unterschiedliche Länge und wie filter ich die Nutzdaten heraus? also, ringbuffer: du weißt sicher, das ist im prinzip eine warteschlange/queue, die nicht "begrenzt" ist. in dieser queue gibt es einträge. zugriffe auf die queue gibt es nur mit push (anstellen) und pop (abarbeiten). für einen kompletten verlgeich aller einträge ist eine queue nicht so recht passend. dazu musst du alle einträge holen, vergleichen und ggf. wieder rauf packen. du möchtest die daten auswerten, schreibst du. dazu machst du immer einen "pop" auf die queue. ist diese noch nciht leer, kriegst du den nächsten eintrag und kannst ihn auswerten. jeder eintrag wird von-wem-auch-immer einfach in die queue ge-pushed, und fertig ist. dabei kann auch die terminierung erfolgen. soweit halbwegens verstanden? :) bye kosmo
Hallo ! Was ist denn wenn ich anstatt einer Terminierung, den String durchsuche? char puffer[8] = { "EISBAER" }; char suche[8] = { "BAER" }; char *ptr; ptr = strstr(puffer,suche); Was ist mit so einer Lösung? Ist so eine Art der Programmierung zum auswerten eines Ringpuffers empfehlenswert?
Stefan wrote: > Was ist mit so einer Lösung? > > Ist so eine Art der Programmierung zum auswerten eines Ringpuffers > empfehlenswert? Nein. Der Grundsatz jeder Basisdatenstruktur sollte sein: So wie ich die Daten an die Struktur übergebe, so will ich sie aus der Datenstruktur wiederhaben. Alles andere: Ask for troubles Was hast du für ein Problem damit einen String den du byteweise in den Ringbuffer schreibst mit einem '\0' Zeichen abzuschliessen? So wie das in C für Strings üblich ist und seit 40 Jahren praktiziert wird.
Nein, ich habe da kein Problem mit ! Ich muss es halt nur extra hinzufügen! Wie ist das denn generell noch mal für mein Verständnis! Ich habe eine ARRAY6] = "SONNE"; Jetzt schreibe ich das ARRAY in meinen Ringpuffer. Dazu muss ich doch jetzt noch explizit das /0 hinzufügen! Korrekt ? Das ARRAY hat ja bereits nen Abschluss mit ner /0, die wird aber nicht mit in den Ringpuffer übernommen, somit müßte ich eigentlich schreiben: ARRAY[8] = "SONNE/0"; Habe ich das richtig auf dem Schirm ?
Stefan wrote: > Wie ist das denn generell noch mal für mein Verständnis! > > Ich habe eine ARRAY6] = "SONNE"; > > Jetzt schreibe ich das ARRAY in meinen Ringpuffer. Dazu muss ich doch > jetzt noch explizit das /0 hinzufügen! Korrekt ? > > Das ARRAY hat ja bereits nen Abschluss mit ner /0 Korrekt. > die wird aber nicht > mit in den Ringpuffer übernommen, somit müßte ich eigentlich schreiben: Das kommt drauf an, wie du die Einstellfunktion in den Ringbuffer schreibst. Ich geh mal davon aus, dass du eine Funktion hast, die 1 Byte in den Ringbuffer stellt. Ich nenn die mal Enqueue. Dann ist es trivial darauf aufbauend eine Funktion zu schreiben, die einen kompletten String, inklusive Terminierung, einstellt
1 | void Enqueue( uint8_t Byte ) |
2 | {
|
3 | ....
|
4 | }
|
5 | |
6 | void EnqueueString( const char* String ) |
7 | {
|
8 | while( *String != '\0' ) |
9 | Enqueue( *String++ ); |
10 | Enqueue( '\0' ); |
11 | }
|
12 | |
13 | int main() |
14 | {
|
15 | char Test[] = "Juhu"; |
16 | |
17 | EnqueueString( Test ); |
18 | EnqueueString( "Noch ein Test" ); |
19 | }
|
Und genauso simpel ist es die gegenteilige Funktion zu schreiben, die, aufbauend auf einer Funktion die ein Byte aus dem Ringbuffer holt, dies mit einem String tut: Sie holt solange Bytes aus dem Ringbuffer bis das '\0' Zeichen erreicht wird und speichert die Bytes in der bereitgestellten Speicherfläche (normalerweise wahrscheinlich ein Array) ab. Inklusive '\0' natürlich. PS: Die traditionellen Namen für diese Funktionen sind Enqueue und Dequeue, da es sich hier um eine Warteschlange handelt, ein FIFO Push und Pop werden normalerweise für Stacks benutzt, also einen LIFO
Hallo kbuchegg! Danke für das Programmbeispiel... Das Auswerten der einzelnen Strings würdest Du über strcmp() machen? Was ist, wenn ich 30 Wörter in meinem Ringpuffer habe? Ist das n. etwas umständlich, anderes rum gibt es überhaupt ne andere Möglichkeit außer dies mit strcmp zu machen? Eine Statemaschine die die einzelnen String überprüft, wäre wohl das sinnvollste, oder ? Was ist Deine Meinung ? Mfg Stefan
Stefan wrote: > Was ist Deine Meinung ? Meine Meinung: Zuallerst sorge dafür, dass dein Programm korrekt funktioniert. Wenn es dann läuft, sieh dir an ob es schnell genug läuft. Tut es das: Super. Fertig. Tut es das nicht: Finde raus, wo die meiste Zeit verbraucht wird (zb. mit einem Profiler) und fang dort zu optimieren an. Das heist nicht, dass es ok ist, wenn man im Vorfeld schludert und der Maschine unnötige Lasten aufbürdet. Es heist aber: Nimm einen normalen Programmierstil her und erst wenn der nachweislich nicht mehr reicht, erst dann fange zu tricksen an. > Das Auswerten der einzelnen Strings würdest Du über strcmp() > machen? Sicher. Warum nicht? > Was ist, wenn ich 30 Wörter in meinem Ringpuffer habe? Dann warten eben 30 Wörter im Ringbuffer, dass sie abgeholt werden und mit ihnen etwas gemacht wird. Solange der Ring- buffer nicht übergeht ist das ja kein Problem. > Ist das n. etwas umständlich, Das weis ich nicht, weil ich nicht weis was du machen willst. > anderes rum gibt es überhaupt ne andere Möglichkeit außer > dies mit strcmp zu machen? Das hat aber erst mal nichts mit dem Ringbuffer zu tun. Gewöhn dir an die Dinge funktional zu trennen. Der Ringbuffer hat eine einzige Aufgabe: Daten zwischenzuspeichern. Es ist nicht Aufgabe des Ringbuffers sich darum zu kümmern woher die Daten kommen bzw. was mit ihnen weiter passiert. Im Ringbuffer werden die Daten (in deinem Fall wohl Strings) zwischengeparkt. Wenn deine Ringbufferfunktionen das fehlerfrei können, dann erfüllen sie ihre Aufgabe zu 100% > Eine Statemaschine die die einzelnen String > überprüft, wäre wohl das sinnvollste, Kann sein, kann aber auch nicht sein. Wieviele verschiedene Wörter hast du denn? Auf die Auswertung eines Wortes folgt ja eine Aktion: Wie ist das geschätzte Verhältnis von Auswertung/Aktion Wo kommt die Eingabe überhaupt her? Möglichkeiten: * plain vanilla linear in einer Tabelle suchen * ebenfalls die Schlüsselwörter in eine Tabelle aber diesmal sortiert. -> Binär suchen * Hashtable * Statemachine. Wobei das das unflexibelste ist, wenn sich die Liste der Schlüsselwörter mal ändert. Auf der anderen Seite könnte man sich ein Programm schreiben, welches die Statemaschine aus der Liste der Schlüsselwörter generiert. Da ich aber notorisch faul bin, würde ich als allererstes mal Option 1 (plain vanilla Tabelle mit linearem Suchen) nahmen, es sein denn die Liste der Schlüsselwörter ist relativ gross oder es stellt sich im Vorfeld heraus, dass das zu langsam wird. Dann würde ich auf eine sortierte Liste mit binärer Suche ausweichen.
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.