Hi an alle! Hätte da mal eine Frage: Wie kann ich die Zeichen aus einem String löschen? Ich hab es schon mit sprintf(&buffer,0), sprintf(&buffer,"") und for(y=0; y<10; y++) { stringReceive[y]=0; } und for(y=0; y<10; y++) { stringReceive[y]=""; } versucht, aber nichts funkioniert richtig. Danke schonmal! Lg Hans
sprintf() ist die schlechteste Lösung ! Das hier ist eigentlich perfekt: >for(y=0; y<10; y++) >{ > stringReceive[y]=0; >} Was funktioniert da nicht ?
Was verstehst du unter "löschen"? Wenn du den String auf Länge Null kürzen willst reicht ein einfaches
1 | string[0] = 0; |
Schau dir am besten erst mal in einem C-Buch an wie Strings in C implementiert sind.
Wenn ich zb. einen String mit 5 Zeichen einlese und ihn dann wieder ausgeben will, dann stimmen nur die ersten 2 Zeichen und in den anderen 3 steht irgendwas, was irgendwann mal im buffer war.
Ein String wird üblicherweise mit einer 0 abgeschlossen, nach dem letzten Zeichen das du in das Array geschrieben hast musst du also eine 0 reinschreiben. Die Ausgabefunktion liest dann nur so lange bis sie auf eine 0 stößt. Aber das steht wirklich in jedem C-Buch.
@Andreas Schwarz Ja das ist mir schon klar. Nur ich lese die Zeichen über die die serielle Schnittstelle ein und speichere die Zeichen eben in einem Buffer. Diesen Buffer will ich dann später wieder über die serielle Schnittstelle senden (das ganze mach ich zu Testzwecken mit Hyperterminal). Nur stimmen immer nur die ersten zwei Zeichen und in den anderen steht immer das gleiche.
Dann solltest Du nur bis dahin lesen, bis wohin Du geschrieben hast. In ASM vergleiche ich dazu die Pointer auf den Ringbuffer. C wird da vermutlich eine komfortablere Möglichkeit bieten. ...
Hans wrote: > @Andreas Schwarz > > Ja das ist mir schon klar. Nur ich lese die Zeichen über die die > serielle Schnittstelle ein und speichere die Zeichen eben in einem > Buffer. Diesen Buffer will ich dann später wieder über die serielle > Schnittstelle senden (das ganze mach ich zu Testzwecken mit > Hyperterminal). Nur stimmen immer nur die ersten zwei Zeichen und in den > anderen steht immer das gleiche. Weil du nur 2 Zeichen eingelesen hast. Nachdem alle Zeichen korrekt eingelesen wurden, musst du hinten drann noch ein 0 Zeichen schreiben. Dieses 0 Zeichen ist wichtig! Erst dieses 0 Zeichen macht aus einem char-Buffer einen String. Alle String-Funktionen wissen über dieses 0 zeichen und beenden dort ihre String Bearbeitung. > Diesen Buffer will ich dann später wieder über die serielle > Schnittstelle senden Wie sendest du denn den String? Um es nochmal klar zu sagen: Dein Problem ist nicht 'Wie lösche ich einen String?'. Dein Problem ist, dass du nicht weist wie Stringverarbeitung generell in C funktioniert.
> Nur ich lese die Zeichen über die die serielle Schnittstelle ein > und speichere die Zeichen eben in einem Buffer. Diesen Buffer > will ich dann später wieder über die serielle Schnittstelle senden Nun, da musst Du offensichtlich mitzählen, wieviele Zeichen im Buffer gespeichert wurden, damit Du weisst, wieviel Zeichen aus dem Buffer wieder gesendet werden sollen. Ist doch logisch, oder?
Unbekannter wrote: >> Nur ich lese die Zeichen über die die serielle Schnittstelle ein >> und speichere die Zeichen eben in einem Buffer. Diesen Buffer >> will ich dann später wieder über die serielle Schnittstelle senden > > Nun, da musst Du offensichtlich mitzählen, wieviele Zeichen im Buffer > gespeichert wurden, damit Du weisst, wieviel Zeichen aus dem Buffer > wieder gesendet werden sollen. schlechter Rat. Anstatt mitzählen ist es besser die Ding in C Manier zu machen. Das bedeutet: Ans Ende des Strings kommt ein '\0'
>Das bedeutet: Ans Ende des Strings kommt ein '\0' Das ist die beste Lösung, setzt aber voraus, daß die low-level-Empfangsroutine das Ende eines gesendeten Strings erkennen können muß. >Wenn ich zb. einen String mit 5 Zeichen einlese und ihn dann wieder >ausgeben will, dann stimmen nur die ersten 2 Zeichen und in den anderen >3 steht irgendwas, was irgendwann mal im buffer war. Das deutet doch wohl darauf hin, daß entweder dein Ringpuffer nicht richtig funktioniert, oder deine Empfangsroutine nur zwei Zeichen dort reinschreibt, asu was für Gründen auch immer. Mit "Strings löschen" hat das nichts zu tun. Als erste Maßnahme würd ich mal jedes empfangene Zeichen sofort zurückschicken, um zu überprüfen, ob die uart-Kommunikation überhaupt richtig funktioniert. Oliver
Ich wäre auch dafür das man beim einlesen der Daten mitzählt wieviele Zeichen gesendet wurden. z.B.
1 | stringReceive[y++]=new_char; |
2 | stringReceive[y]='\0'; |
somit hat er automatisch das Problem mit dem Stringende Zeichen gelöst, egal wieviele Zeichen er einließt.
Oliver wrote: >>Das bedeutet: Ans Ende des Strings kommt ein '\0' > > Das ist die beste Lösung, setzt aber voraus, daß die > low-level-Empfangsroutine das Ende eines gesendeten Strings erkennen > können muß. Oh. Die low level Empfangsroutine könnte zb. prophylaktisch nach jedem empfangenen Zeichen sofort eine '\0' hinten dran hängen. Der Zeitbedarf dafür ist vernachlässigbar und man ist damit immer auf der sicheren Seite.
> schlechter Rat. > Anstatt mitzählen ist es besser die Ding in C Manier zu machen. Nö, kein schlechter Rat. Denn er möchte eine transparente Verbindung, die alles zurückschickt, was ankommt. Null-Bytes können also auch ankommen und müssen auch zurückgeschickt werden.
Die Frage ist jetzt, was wird gebraucht? Ein funktionierender Ringbuffer oder ein C-konformer String? Langsam erkenne ich, warum ich mich vor C drücke, es gibt da einfach zu viele Konventionen und Regeln, die man nicht unbedingt alle gut heißen muss... ;-) ...
> Langsam erkenne ich, warum ich mich vor C drücke, es gibt da einfach > zu viele Konventionen und Regeln, die man nicht unbedingt alle gut > heißen muss... ;-) So ist es. Mir ist es neulich auch so ergangen. In letzter Zeit habe ich ausschließlich in einer richtigen Programmiersprache, nämlich Haskell programmiert. Nun musste ich aber wieder mal einen Controller in C programmieren. Ekelhaft. Einfach schlimm.
Hannes Lux wrote: > Langsam erkenne ich, warum ich mich vor C drücke, es gibt da einfach zu > viele Konventionen und Regeln, die man nicht unbedingt alle gut heißen > muss... ;-) Das hat überhaupt nichts mit C zu tun. Keine Programmiersprache kann Dir die Entscheidung abnehmen, ob es sich um einen Text oder um Binärdaten handelt. Bei Binärdaten mußt Du mitzählen. Bei Textdaten kannst Du ein Endezeichen setzen oder auch mitzählen. Nur wenn Du Textdaten mit Textfunktionen bearbeiten willst, mußt Du dahinter ein Endezeichen anfügen. Peter
Unbekannter wrote: >> schlechter Rat. >> Anstatt mitzählen ist es besser die Ding in C Manier zu machen. > > Nö, kein schlechter Rat. Denn er möchte eine transparente Verbindung, > die alles zurückschickt, was ankommt. Null-Bytes können also auch > ankommen und müssen auch zurückgeschickt werden. Wenn der Begriff "String" im Spiel ist, dann gehe ich auch davon aus, dass er "String" meint und nicht Binärdaten.
Hannes Lux wrote: > Langsam erkenne ich, warum ich mich vor C drücke, es gibt da einfach zu > viele Konventionen und Regeln, die man nicht unbedingt alle gut heißen > muss... ;-) :-) Alles halb so wild. Mann muss nur in erster Linie die Dinge richtig benennen und wissen wovon man spricht. Aber das muss man überall. In Assembler musst du selbst darüber Buch führen, was denn nun ein Byte in einem Register (oder Speicher) bedeutet. In einer typisierten Sprache wie C übernimmt der Compiler diese Buchführung. Und dann gibt es noch die Datentypen, die in C tatsächlich auf Konventionen beruhen, zb. String. Im Moment fällt mir aber kein 2tes Beispiel dazu ein, der "String" Dtaentyp ist in C tatsächlich der einzige Datentyp, der aus einem Basistyp + Konvention besteht. Allerdings musst du dich ja auch in Assembler mit dir selbst einigen, wie du Texte repräsentierst: mittels Zeichenzähler oder mit einer speziellen Endekennung.
Karl heinz Buchegger wrote u.a.: > Wenn der Begriff "String" im Spiel ist, dann gehe ich auch > davon aus, dass er "String" meint und nicht Binärdaten. Es soll Leute geben, für die ist "String" die Taste links unten auf der Tastatur... ;-) Ich vermute ja, er braucht 'nen Ringbuffer. Und wenn es unbedingt (wegen der Weiterverarbeitung) ein String sein muss, dann sollte man ihn erst auswerten, wenn er fertig angekommen ist, also wenn das Ende-Zeichen (0) empfangen wurde. Soll das Echo aber sofort erfolgen (nicht erst, nachdem die 0 empfangen wurde), dann ist Mitzählen angesagt. ...
Karl heinz Buchegger wrote u.a.: > Alles halb so wild. Sicher, wenn man es kann, ist es ja keine Kunst mehr. Mir ist es aber zuviel auf einmal. Da ist mir ASM symphatischer. > Mann muss nur in erster Linie die Dinge richtig benennen > und wissen wovon man spricht. > > Aber das muss man überall. > Richtig, das sehe ich auch so. > In Assembler musst du selbst darüber Buch führen, was > denn nun ein Byte in einem Register (oder Speicher) bedeutet. Und das ist gut so. Da pfuscht mir wenigstens kein Compiler ins Handwerk und optimiert mir gutgemeinte Dinge weg. Ich habe auch nicht das Rätselraten, ob und wie die Features des speziellen AVRs genutzt werden. Da ich in meinen (recht kleinen und bescheidenen) Programmen kaum "rechnen" nuss, komme ich mit ASM ganz gut zum Ziel. > In einer typisierten Sprache wie C übernimmt der Compiler > diese Buchführung. Und dann gibt es noch die Datentypen, > die in C tatsächlich auf Konventionen beruhen, zb. String. Ich dachte immer, dass Texte in Arrays aus Char gelegt werden? Denke ich zumindest mal gelesen zu haben. > Im Moment fällt mir aber kein 2tes Beispiel dazu ein, > der "String" Dtaentyp ist in C tatsächlich der einzige > Datentyp, der aus einem Basistyp + Konvention besteht. > Allerdings musst du dich ja auch in Assembler mit dir selbst > einigen, wie du Texte repräsentierst: mittels Zeichenzähler > oder mit einer speziellen Endekennung. Es kommt immer darauf an, was ich mit dem Text anfangen will. Meine aktuelle Textausgaberoutine für LCD wertet neben der Ende-Kennung 0 auch chr$(13) (Rest der Zeile löschen und neue Zeile beginnen) und einige selbstdefinierte Steuerzeichen (CLS, Home, Blinkbeginn/Blinkende/Blinkaus) und Platzhalter für Zahlenausgabe (Ziffernausgabe aus reserviertem SRAM-Bereich) aus. Muss ich Texte parsen, dann muss ich natürlich anders herangehen. ...
Hannes Lux wrote: > Und das ist gut so. Da pfuscht mir wenigstens kein Compiler > ins Handwerk Ich seh schon. Ich werde dich nie zu C überreden können :-) >> diese Buchführung. Und dann gibt es noch die Datentypen, >> die in C tatsächlich auf Konventionen beruhen, zb. String. > > Ich dachte immer, dass Texte in Arrays aus Char gelegt > werden? Denke ich zumindest mal gelesen zu haben. Das stimmt schon. Zusätzlich gibt es aber noch die Konvention, das das letzte Zeichen eines Strings eine 0 sein muss. Niemand sagt ja, dass der String das Array komplett ausfüllen muss. > > Meine aktuelle Textausgaberoutine für LCD wertet neben der Ende-Kennung > 0 Na also. Genau das ist ein String, so wie C ihn versteht. Eine Alternative (frühe Pascal Compiler haben gerne so gearbeitet) wäre es, wenn zb die ersten beiden Bytes in einem String-Datentyp einen Zeichenzähler beinhalten. > auch chr$(13) (Rest der Zeile löschen und neue Zeile beginnen) und > einige selbstdefinierte Steuerzeichen (CLS, Home, > Blinkbeginn/Blinkende/Blinkaus) und Platzhalter für Zahlenausgabe > (Ziffernausgabe aus reserviertem SRAM-Bereich) aus. Das kannst du in C genauso machen. Genauso wie das in deinem String Spezialzeichen sind, die bei der Ausgabe speziell behandelt werden, genauso kann man das auch in C machen.
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.