Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : whithespace aus string entfernen



gorba
02-02-2006, 11:08
hallo

hat jemand eine gute (effiziente) idee wie man whitespaces aus einem string entfernen kann?
strtok() mit dem einem delimeter der kein leerzeichen ist, aber dafür müsste ich wissen was nach den spaces kommt.
ich dreh mich momentan an der stelle und hoffe darum auf input ^^
grz

geronet
02-02-2006, 19:13
Das Feld ( = string) nach (int) 32 ( = Leerzeichen) absuchen, den Teil bis dorthin in einen neuen String kopieren und im Rest wieder weitersuchen bis zum nächsten Leerzeichen, diesen Teil wieder reinkopieren (aber ohne Leerzeichen) und so weiter bis der String zu ende ist ;)

peschmae
02-02-2006, 20:39
Könntest den natürlich auch in denselben String kopieren. Ich meine, der kann ja nur kürzer werden...

MfG Peschmä

gorba
03-02-2006, 09:36
wie wärs mit nem char *pt der auf ein element des arrays zeigt.
dan kann ich mit einem vergleich (*pt = LEERZEICHEN) einfach herausfinden obs an dieser stelle ein leerzeichen hatt. wenn ja setze ich pt++ und bin das leerzeichen los.

peschmae
03-02-2006, 19:05
pt++ bist du beim nächsten Zeichen. Und? Das ist ja dann immer noch da. Oder willst du das gar nicht wirklich richtig entfernen sondern quasi nur beim Auslesen überspringen?

MfG Peschmä

gorba
06-02-2006, 11:12
es is noch da aber wer merkt das?
da die adresse zum leerzeichen nicht mehr bekannt ist.. niemand :)

die lösung mit strncpy mit dem gleichen string hab ich auch erwogen. aber das schien mir dan doch zu unsauber. so kann ich überall mit meinem char * arbeiten und bin den "original" string los. hatt den vorteil, dass ich strtok nicht brauche um meinen string an sscanf zu übergeben. die funktion is mir irgendwie unsymphatisch. da finde ich den char * schon sexy!

quinte17
06-02-2006, 15:51
bei führenden leerzeichen ist der pointer schon einfacher keine frage :D aber dies geht aus deinem thread oben leidern nicht so richtig hervor..

greetz

panzi
06-02-2006, 17:18
Also du willst nur whitespaces am anfang rauslöschen? Wenn du alle whitespaces löschen wollen würdes wäre das in python (ich weiß, jetzt net sehr produktiver der beitrag, wenn du c/c++ programmierst) das so:

s = ''.join(c for c in s if not c.isspace())

Achja, vor langer Zeit hab ich mal angefangen den std::string zu überladen und ihm ein paar zusatzfunktionen zu verpassen. Nur die Trim Funktionen hab ich damals implementiert:

#ifndef LIBPANZI_STRING_H___
#define LIBPANZI_STRING_H___

#include <list>
#include <string>
#include <iostream>

namespace libpanzi {

template< typename _CharT, typename _Traits, typename _Alloc >
class basic_string : public std::basic_string< _CharT, _Traits, _Alloc > {
private:

inline string &_M_ltrim( size_type __n, _CharT *__data, size_type __size );

public:

string(const _Alloc &__a)
: std::basic_string( __a ) {}
string(const basic_string< _CharT, _Traits, _Alloc > &__str)
: std::basic_string( __str ) {}
string(const basic_string< _CharT, _Traits, _Alloc > &__str, size_type __pos, size_type __n=npos)
: std::basic_string( __str, __pos, __n ) {}
string(const string< _CharT, _Traits, _Alloc > &__str, size_type __pos, size_type __n, const _Alloc &__a)
: std::basic_string( __str, __pos, __n, __a) {}
string(const _CharT *__s, size_type __n, const _Alloc &__a=_Alloc())
: std::basic_string( __s, __n, __a ) {}
string(const _CharT *__s, const _Alloc &__a=_Alloc())
: std::basic_string( __s, __a ) {}
string(size_type __n, _CharT __c, const _Alloc &__a=_Alloc())
: std::basic_string( __n, __c, __a ) {}

virtual ~basic_string(void) {}

inline basic_string< _CharT, _Traits, _Alloc > &trimnl (void);
inline basic_string< _CharT, _Traits, _Alloc > &rtrimnl(void);
inline basic_string< _CharT, _Traits, _Alloc > &ltrimnl(void);
inline basic_string< _CharT, _Traits, _Alloc > &trim (const _CharT *__chars = " \t\r\n\v");
inline basic_string< _CharT, _Traits, _Alloc > &ltrim (const _CharT *__chars = " \t\r\n\v");
inline basic_string< _CharT, _Traits, _Alloc > &rtrim (const _CharT *__chars = " \t\r\n\v");
inline basic_string< _CharT, _Traits, _Alloc > &trim (size_type __n);
inline basic_string< _CharT, _Traits, _Alloc > &ltrim (size_type __n);
inline basic_string< _CharT, _Traits, _Alloc > &rtrim (size_type __n);

int compare_ignore_case(const basic_string< _CharT, _Traits, _Alloc > &__str) const;
int compare_ignore_case(size_type __pos, size_type __n, const basic_string< _CharT, _Traits, _Alloc > &__str) const;
int compare_ignore_case(size_type __pos1, size_type __n1, const basic_string< _CharT, _Traits, _Alloc > &__str, size_type __pos2, size_type __n2) const;
int compare_ignore_case(const _CharT *__s) const;
int compare_ignore_case(size_type __pos, size_type __n1, const _CharT *__s) const;
int compare_ignore_case(size_type __pos, size_type __n1, const _CharT *__s, size_type __n2) const;

std::list< basic_string< _CharT, _Traits, _Alloc > > split( _CharT token = ' ' ) const;
};

string &string::_M_ltrim( size_type __n, _CharT *__data, size_type __size ) {
size_type __pos_to = 0, __pos_from = __n;
while( __pos_from < __size ) {
__data[ __pos_to ] = __data[ __pos_from ];
++ __pos_to;
++ __pos_from;
}
return erase( __size - __n );
}

string &string::trimnl(void) {
return ltrim().rtrim();
}

string &string::rtrimnl(void) {
return rtrim( " \t\r\n" );
}

string &string::ltrimnl(void) {
return ltrim( " \t\r\n" );
}

string &string::trim(const _CharT *__chars = " \t\r\n\v") {
return lterim( __chars ).rtrim( __chars );
}

string &string::ltrim(const _CharT *__chars = " \t\r\n\v") {
_CharT *__data = data();
size_type __size = size();
size_type __n = 0;
while( __n < __size && std::strchr( __char, __data[ __n ] ) != NULL )
++ __n;
return _M_ltrim( __n, __data, __size );
}

string &string::rtrim(const _CharT *__chars = " \t\r\n\v") {
_CharT *__data = data();
size_type __n = size() - 1;
while( __n > 0 && strchr( __chars, __data[ __n ] ) != NULL )
-- __n;
return erase( ++ __n );;
}

string &string::trim(size_type __n) {
return ltrim( __n ).rtrim( __n );
}

string &string::ltrim(size_type __n) {
return _M_ltrim( __n, data(), size() );
}

string &string::rtrim(size_type __n) {
return erase( size() - __n );
}

typedef basic_string< char > string;
} // namespace libpanzi

#endif // LIBPANZI_STRING_H___

gorba
07-02-2006, 10:47
wiso nur am anfang? ich kann doch so auf irgendwelche leerzeichen aller art (linefeeds, whitespace, tabs etc.) aus dem ganzen string entfernen.

wie kann ich den so ein schönes code fenster erzeugen? dan poste ich mal den code.

panzi
07-02-2006, 13:51
Da gibt's nen Button '#' mit dem du die code tags einfügst.
Die wären dann so, nur statt < und > nimmt man [ und ] (was ich ja da net nehmen kann, denn sonst tätest die ja nicht sehn weils wieder eine code section einfügen würde).
<CODE></CODE>

peschmae
07-02-2006, 16:52
wiso nur am anfang? ich kann doch so auf irgendwelche leerzeichen aller art (linefeeds, whitespace, tabs etc.) aus dem ganzen string entfernen.


Das kommt dann jetzt wirklich sehr drauf an was du damit machen willst. Aber grundsätzlich geht das so eigentlich nicht. Ich meine für C-Strings übergibst du ja normalerweise einen Pointer auf den ersten Char. D.h. wenn der Pointer eins weiter ist dann wird das erste Zeichen weggelassen - aber das kannst du ja nicht für ein Leerzeichen mitten im String machen, weil das was du einer Funktion übergibts normalerweise nur die Adresse des ersten Chars ist...

Ich glaub irgendwie reden wir aneinander vorbei :D

MfG Peschmä

gorba
08-02-2006, 07:08
hier mal die funktion um eine line zu holen und der aufruf zu rem_whites



void get_next_line(){
int ret = 0;
int i = TRUE;

line_buffer_reset();
fgets(line_buffer , MAX_LINE_LEN, fdp);
line_count++;

line = line_buffer;
rem_whites(); // --> hier werden die whitespaces entfernt
while(TRUE == i){
if(strncmp(line,"\0",2) == 0){
get_next_line();
}
else{
i = FALSE;
}
}
}

rem_whites selber:



static int rem_whites(){
char whitespace;
char comment;
char lf;
int c = 0, i = 0;

whitespace = ' ';
comment = '#';
lf = '\n';

while(*line){
if(whitespace == line[0]){ // kann eventuell später was auslesen...
c++;
line++;
}
if(comment == line[0]){ // kann dieses mal warscheindlich nichts auslesen...
c++;
line[0] = '\0';
}
if(lf == line[0]){ // kann ich dieses mal etwas auslesen... ?
c++;
line[0] = '\0';
}
if(whitespace != line[0] && comment != line[0] && lf != line[0]){ // ... ich will endlich auslesen!
break;
}
}
}

info:
static char *line;
static char line_buffer[MAX]

wenn ich nun whitespaces entfernen wil die nicht am anfang stehen lasse ich meinen pointer auf ein bestimmtes element zeigen und rufe rem_whites auf. Ich bin Wort orientiert und so weis ich zimlich genau wo leerzeichen sein könnten. ich weis nur nicht wiviele :)

Joghurt
10-02-2006, 18:05
Globale Variablen sind böse!

Das ist jetzt kein dummer Spruch, sondern ein freundlicher Tipp. Gewöhne es dir ab, du hast später nur Ärger damit; ich spreche aus Erfahrung.

gorba
13-02-2006, 11:32
habe selbst schon (sehr) böse erfahrungen damit gemacht. Darum benutze ich nur modul- globale variabeln da es manchmal unumgänglich ist. (ok.. nicht ganz, aber es macht es sehr viel einfacher)

Pingu
13-02-2006, 14:19
Hi,

also ich habe mir ein ähnliche Funktion "gebastelt":


int trim(char *str) {

char *_tmp = str;

if (*str == '\0') return false;

do {

while ((*_tmp == ' ') ||
(*_tmp == '\r') ||
(*_tmp == '\n'))
_tmp++;

*(str++) = *(_tmp++);

} while (*_tmp != '\0')

*str = '\0';

return true;

} // function trim()


Das schön ist, daß man in der inneren While-Schleife einfach die Zeichen hinzufügen kann, die man nicht haben möchte.

Pingu

gorba
14-02-2006, 13:21
sexy! :) ist eigentlich noch ein interessantes Thema. Solange bis man das ding einmal geschriben hatt.