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
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
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.