# Ganz blöde Frage: Leerzeichen entfernen?



## jccTeq (29. Oktober 2004)

Morgähn!

Per Suche hatte ich keinen Erfolg, darum stell ich die Frage einfach mal... so blöd sie auch sein mag, man vergisst beim Entwickeln komplexester Programme schnell mal das Einfachste vom Einfachen. 

Wie entfernt man führende und abschließende Leerzeichen in einem String in C++? Dabei darf das sowohl ein Character Array als auch ein Ansi-String sein. Das ist mir egal. In C# gibts dafür die Funktion trim, welche es auch in diversen anderen Programmiersprachen gibt, jedoch konnte ich in C++ nix davon finden. Gibts da sowas auch? Oder muss ich das selber implementieren (wie so vieles andere auch)?

Danke!

Gruß,
Hendrik


----------



## MFC openGL (29. Oktober 2004)

Ich wüsste keine Funktion die das macht, daher würde ich den String in ein Char[] konvertieren, und dann von char[0] und char[strlen(char)] nachschaun ob da ein ' ' ist, wenn ja einfach um 1 nach links verschieben, oder das letzte Zeichen gegen '\0' ersetzten, wieder zurückkonvertieren nach String und fertig biste...



> Oder muss ich das selber implementieren (wie so vieles andere auch)?


Kann ja nicht alles schon fertig sein, sonst könnte ja jeder nach dem Baukastenprinzip programmieren


----------



## Tobias K. (29. Oktober 2004)

moin



```
char mit[100]={"Leerzeichen sollen entfernt werden !"};
char ohne[100];

for( int i=0; i<strlen(mit); i++)
{
     if(mit[i] != ' ')
          ohne[l++] = mit[i];
}
```

Sollte funktionieren, hab es aber nciht getestet.


mfg
umbrasaxum


----------



## Thomas Kuse (29. Oktober 2004)

Hier mal ein Beispiel für Visual C++ :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/vclrfCStringTTrim.asp


----------



## canuzzi (29. Oktober 2004)

Variante 

```
char mit[100]={"Leerzeichen sollen entfernt werden !"};
char ohne[100];

for( ;*mit!='\0' ; mit++)
{
     if(!isspace(mit))   /* ist in ctype.h definiert */
          *ohne++ = *mit;
}
```


----------



## jccTeq (29. Oktober 2004)

@all: danke, werd das mal verfeinern! 

@thomas: ich arbeite unter Linux, aber danke trotzdem.


----------



## canuzzi (29. Oktober 2004)

Hi, hab da ein paar Sachen vergessen zu erlaeutern, a - die Zeigerversion funktioniert so nur in einer Funktion/da es sonst mit den Vektortyp kollidiert. Ausserdem musste natuerlich noch mit '\0' abschliessen. Also (getestet) :

```
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

void remove_space(char *,char *);

int main()
{
   char mit[100]={"Leerzeichen sollen entfernt werden !"};
   char ohne[100];

   remove_space(mit,ohne);
   printf("%s\n",ohne);
   return 0;
}

void remove_space(char *s, char *t) {
   for( ;*s!='\0' ;s++) {
     if(!isspace(*s))   /* ist in ctype.h definiert */
          *t++ = *s;
     }
     *t='\0';
}
```

und noch eine Variante fuer die Remove Space Funktion mit nur einem Uebergabeparameter -- der Source String wird direkt veraendert.


```
void remove_space(char *s) {
   char *tmp;
   tmp=s;
   for( ;*s!='\0' ;s++) {
     if(!isspace(*s))   /* ist in ctype.h definiert */
          *tmp++ = *s;
     }
     *tmp='\0';
}
```


----------



## Fabian H (29. Oktober 2004)

Wieso lässt du die Funktion nicht einfach einen Pointer auf das erste Zeichen, das kein Whitespace ist, zurückgeben?

```
char *ltrim(char *s)
{
    while (*s && *s <= 32)
        s++;

    return s;
}

/* ... */
printf(":%s:\n", ltrim("    foobar"));
```
Die erste Bedingung der While Schleife sorgt dafüer, dass \0 nicht als Whitespace erkannt wird (= Ende des Strings, da ist s++ keine gute Idee )


----------



## canuzzi (29. Oktober 2004)

Was hast du da jetzt gewonnen, wenn du den ganzen whitespace entfernen willst?


----------



## Fabian H (29. Oktober 2004)

Die Frage war:


> Wie entfernt man führende und abschließende Leerzeichen in einem String in C++?


Sprich: Alle Leerzeichen im gesamten String entfernen ist nicht das, was jccTeq wollte.

Ausserdem braucht man bei deiner Lösung noch ein zweites Array.


----------



## canuzzi (29. Oktober 2004)

Braucht man in Version zwei nicht, und der abschliessende whitespace wird bei dir nicth entfernt. Die erste Version war nur eine Variante des Vorposters, die zweite Version braucht nur einen Zusaetzlichen charpointer. Der Nachteil bei deiner Version waere zusaetzlich, dass ich gar nicht mehr weiss, wie lang mein Array denn jetzt noch ist.  Da es jetzt um die Anzahl der fuehrenden Leerzeichen verkuerzt ist. Sowas halte ich fuer aeusserst schlechtes Design in Hinblick auf Fehleranfaelligkeit.


----------



## canuzzi (29. Oktober 2004)

Version: nur fuehrenden und abschliessenden whitespace:

```
void strim(char *s) {
   char *p;
   p=s;
   while (isspace(s++))
       ;
   for (;*s!='\0';s++)
       *p++=s;
   while(isspace(--p))
        ;
     ++p='\0';
}
```


----------



## Fabian H (29. Oktober 2004)

> Nachteil bei deiner Version waere zusaetzlich, dass ich gar nicht mehr weiss, wie lang mein Array denn jetzt noch ist. Da es jetzt um die Anzahl der fuehrenden Leerzeichen verkuerzt ist. Sowas halte ich fuer aeusserst schlechtes Design in Hinblick auf Fehleranfaelligkeit.


Das "Array" ist dann genauso lang wie vorher, es wird nicht verändert.


```
char *psz = "    foobar";

printf(":%s:\n", ltrim(psz));
printf(":%s:\n", psz);


/* und sogar mit malloc geht's wunderbar */
char *psz, *pszf;
psz = pszf = (char*)malloc(20 * sizeof(char));
strcpy(psz, "    Foobar");
psz = ltrim(psz);

free(pszf) /* kein Problem hier */
```
Also ich sehe da kein Problem drin.
Im Gegenteil, zwei Arrays sind sogar speicherverschwendung.


----------



## canuzzi (29. Oktober 2004)

Doch ist es!
Dein Array 0... symbolisieren  die pointer
< 0 > < 1 > < 2 > < 3 > < 4 > < 5 > .... < N >
Du setzt den Pointer Auf den ersten !whitespace zB < 3 >
Dann gibts du dieses Array der dimension N-3 zurueck
< 3 > < 4 > < 5 > .... < N >
Da jemanden jetzt eventuel nicht klar ist, dass er jetzt einen um 3 Verkuerztes Array hat, versucht er spaeter vielleicht noch N Zeichen in das Array zu schreiben.

Und ich benutze kein zweites Array!


----------



## Mr.Undertaker (29. Oktober 2004)

Und wie wärs mit der STL. Mit std::string passiert euch sowas nicht  !
Er fragte doch nach einer C++ Lösung oder? (sehe hier malloc   )


```
void trim(std::string& strInput)
{
   // string von VORN durchgehen
   for(size_t i=0; i<strInput.length(); i++)
   {
      if(strInput[i]==' ') 
      {
           strInput.erase(0,1);	//erstes Zeichen löschen
           i=-1;		//auf -1 = nächsten Durchlauf 0 (wegen String-Kürzung)
      }
     else break;
   }

   // string von HINTEN durchgehen
   for(size_t i=strInput.length()-1; i>0 ;i--)
   {
        if(strInput[i]==' ') strInput.erase(i);	//letztes Zeichen löschen
        else break;
   }
}
```


----------

