Forum: Mikrocontroller und Digitale Elektronik String leeren


von Hans (Gast)


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

von holger (Gast)


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 ?

von Katzeklo (Gast)


Lesenswert?

Wäre noch folgende Variante:
1
for(y=0; y<10; y++)
2
{
3
   stringReceive[y]=' ';
4
}

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

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.

von Hans (Gast)


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.

von Andreas S. (andreas) (Admin) Benutzerseite


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.

von Hans (Gast)


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.

von Hannes L. (hannes)


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.

...

von Karl H. (kbuchegg)


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.

von Unbekannter (Gast)


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?

von Karl H. (kbuchegg)


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'

von Oliver (Gast)


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

von OlFi (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


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.


von Unbekannter (Gast)


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.

von Hannes L. (hannes)


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

...

von Unbekannter (Gast)


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.

von Peter D. (peda)


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

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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.

von Hannes L. (hannes)


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.

...

von Hannes L. (hannes)


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.

...

von Karl H. (kbuchegg)


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.

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
Noch kein Account? Hier anmelden.