String Hilfe gesucht

Gast #1311198
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
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.
1
#define GENUG       50
2
  char  meinString[GENUG] = "read portb";
3
  memmove( meinString, meinString+strlen("read "), strlen("portb")+1 );
4

5
  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:
1
#define GENUG       50
2

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

6
    restlicherString = langerString + strlen( "read " );
7
    // jetzt zeigt restlicherString auf den String "portb",
8
    // davor steht der alte Anfang und wird einfach nicht
9
    // mehr benutzt
10
    printf( "jetzt nur noch %s", restlicherString ); // "portb"
noch eine dritte Möglichkeit wäre, den alten String mit
strtok() aufzuteilen. Aber keiner mag strtok(), und hier ist es
vielleicht auch übertrieben.
1
#include <stdio.h>
2
#include <string.h>
3

4

5
#define GENUG       50
6

7
int main()
8
{
9
  char  meinString[GENUG] = "read portb";
10

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

19
  if( p_secondToken )
20
  {
21
    printf( "jetzt nur noch %s\n", p_secondToken ); // "portb"
22
  }
23
  return 0;
24
}
Gast
Erstmal danke für deine ausreiche Hilfe!
Eine Frage bleibt jedoch leider offen...
Der Compiler meckert bei
1
     
2
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
1
 
2
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
Nachtrag zum strtok():
Ich habe eben das Beispiel mit avr-gcc übersetzt, der kennt
gar kein strtok().
Stattdessen geht strtok_r():
1
#define GENUG       50
2
  char  meinString[GENUG] = "read portb";
3
  char *p_save;
4
  
5
  // beim ersten Aufruf von strtok() wird an der Stelle des
6
  // Leerzeichens in meinString[] eine terminierende 0 geschrieben und
7
  // ein Zeiger auf "read" geliefert:
8
  char *p_secondToken = strtok_r( meinString, " ", &p_save );
9
  // der zweite Aufruf (ohne String) liefert das nächste Token, hier
10
  // auch gleichzeitig das letzte ("portb"):
11
  p_secondToken = strtok_r( NULL, " ", &p_save );
12
  
13
  if( p_secondToken )
14
  {
15
    printf( "jetzt nur noch %s\n", p_secondToken ); // "portb"
16
  }

(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)

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.