String Hilfe gesucht

Gast #1311198
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
#1311210
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.
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"
#1311220
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.
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 #1311242
Lesenswert?

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
#1311263
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren