www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik String Hilfe gesucht


Autor: TDK (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
ich habe ein kleines Problem.
Ich würde gerne die ersten 3 bzw. 4 Zeichen aus einem String löschen.
Wie wäre das möglich? (Programmiersprache C)
Gemacht werden sollte das für die Serielle Schnittstelle.
Ich bekomme von der Schnittstelle an den Controller
"read portb" oder ähnliches - nachdem ich read oder set abgefragt habe 
möchte ich dies aus meinen String löschen so das nur noch "portb" drinen 
stehen würde.
Mit strncpy geht das leider nicht da nur die ersten Zeichen ausgelesen 
werden. Desweiteren geht right() nicht da die zeichen von rechts gesehen 
nicht immer gleich lang sind!
Vielen dank schon mal
mfg
TDK

: Verschoben durch Moderator
Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Spontan fallen mir zwei Möglichkeiten ein:
- mit memmove() kann man Speicherbereiche verschieben,
  die sich auch überlappen dürfen wie hier.
  Als Länge muß man strlen(derrestlichestring)+1 angeben, damit
  auch die abschließende 0 mitkopiert wird.
#define GENUG       50
  char  meinString[GENUG] = "read portb";
  memmove( meinString, meinString+strlen("read "), strlen("portb")+1 );

  printf( "jetzt nur noch %s\n", meinString ); // "portb"
- Möglicherweise braucht man gar nicht kopieren, sondern lässt
  den String einfach stehen und verwendet halt nur den hinteren Teil.
  Beispiel:
#define GENUG       50

    char  langerString[GENUG] = "read portb";
    char *restlicherString;

    restlicherString = langerString + strlen( "read " );
    // jetzt zeigt restlicherString auf den String "portb",
    // davor steht der alte Anfang und wird einfach nicht
    // mehr benutzt
    printf( "jetzt nur noch %s", restlicherString ); // "portb"

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
noch eine dritte Möglichkeit wäre, den alten String mit
strtok() aufzuteilen. Aber keiner mag strtok(), und hier ist es
vielleicht auch übertrieben.
#include <stdio.h>
#include <string.h>


#define GENUG       50

int main()
{
  char  meinString[GENUG] = "read portb";

  // beim ersten Aufruf von strtok() wird an der Stelle des
  // Leerzeichens in meinString[] eine terminierende 0 geschrieben und
  // ein Zeiger auf "read" geliefert:
  char *p_secondToken = strtok( meinString, " " );
  // der zweite Aufruf (ohne String) liefert das nächste Token, hier
  // auch gleichzeitig das letzte ("portb"):
  p_secondToken = strtok( NULL, " " );

  if( p_secondToken )
  {
    printf( "jetzt nur noch %s\n", p_secondToken ); // "portb"
  }
  return 0;
}

Autor: TDK (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erstmal danke für deine ausreiche Hilfe!
Eine Frage bleibt jedoch leider offen...
Der Compiler meckert bei
     
memmove( input, input+strlen("read "), strlen("portb")+1 );
mit folgender Meldung:
[pre]
*** Error 90 "seriell.c" Line 47(39,40): Attempt to create a pointer to 
a constant
[\pre]
Den gleichen Fehler habe ich wenn ich bei
 
if(strncmp(*input,*set, 3) == 0)
statt *set = "set" verwende... Gibt es dafür eine elegantere Lösung? (so 
muss ich nämlich für jede mögliche Antwortmöglichkeit auch einen eigenen 
char erstellen :(
Danke schon mal
mfg
TDK

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
/pre geht besser als \pre...

- welcher Compiler? Bei mir hat mein Beispiel kompiliert!
- wie ist input vereinbart?

und dann musst du natürlich strlen("read ") und strlen("portb")
je nach deinem String anpassen!

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag zum strtok():
Ich habe eben das Beispiel mit avr-gcc übersetzt, der kennt
gar kein strtok().
Stattdessen geht strtok_r():
#define GENUG       50
  char  meinString[GENUG] = "read portb";
  char *p_save;
  
  // beim ersten Aufruf von strtok() wird an der Stelle des
  // Leerzeichens in meinString[] eine terminierende 0 geschrieben und
  // ein Zeiger auf "read" geliefert:
  char *p_secondToken = strtok_r( meinString, " ", &p_save );
  // der zweite Aufruf (ohne String) liefert das nächste Token, hier
  // auch gleichzeitig das letzte ("portb"):
  p_secondToken = strtok_r( NULL, " ", &p_save );
  
  if( p_secondToken )
  {
    printf( "jetzt nur noch %s\n", p_secondToken ); // "portb"
  }

(strtok() ist ohnehin nicht ganz ungefährlich, da es zwischen
zwei Aufrufen in statischem Speicher Daten hält und deshalb
nicht gleichzeitig zwei Strings zerlegt werden können, mit
strtok_r() geht das sicherer)

Autor: TDK (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habs mit mp-lab und ccs-c compiler probiert.
Ist aber auch egal wenns mit pointern geht ;-)
Auf jeden fall vielen dank an dich ;-)
mfg

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.