www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik String leeren


Autor: Hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sprintf() ist die schlechteste Lösung !

Das hier ist eigentlich perfekt:

>for(y=0; y<10; y++)
>{
>   stringReceive[y]=0;
>}

Was funktioniert da nicht ?

Autor: Katzeklo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wäre noch folgende Variante:
for(y=0; y<10; y++)
{
   stringReceive[y]=' ';
}

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was verstehst du unter "löschen"? Wenn du den String auf Länge Null 
kürzen willst reicht ein einfaches
string[0] = 0;
Schau dir am besten erst mal in einem C-Buch an wie Strings in C 
implementiert sind.

Autor: Hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Unbekannter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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'

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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

Autor: OlFi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich wäre auch dafür das man beim einlesen der Daten mitzählt wieviele 
Zeichen gesendet wurden.

z.B.
stringReceive[y++]=new_char;
stringReceive[y]='\0';

somit hat er automatisch das Problem mit dem Stringende Zeichen gelöst, 
egal wieviele Zeichen er einließt.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.


Autor: Unbekannter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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... ;-)

...

Autor: Unbekannter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

...

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.