Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Strings verbinden ...

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: [ 1 ] > 2 < [ 3 ] [ 4 ]
010
25.05.2005, 12:57 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)



Zitat:

Und jetzt will ich eben eine Funktion, die mir die Leerzeichen aus einer Zeichenkette löscht. Wie würdest es denn du machen?!


anders

aber wenn du es unbedingt mit einem char-array machen willst...

mir scheint da zum einen du hast einen Designfehler... wenn deine Klasse CString heisst (von der MFC geklaut ) dann müsstest du doch eigentlich sinnvoller Weise jedes Objekt deiner Klasse als member zumindest ein array von chars haben... (die den string reprästentieren)...

wenn du dann die Leerzeichen kicken willst brauch deine Mehtode doch gar keinen Zeiger mehr auf diesen String selber da du ja schon direkt über die Membervariable zugreifen kannst...


also vom Design her schon mal erstmal in der Art

C++:
class CString{

  public:
    CString();
    CString(const char* str);
    Remove_Spaces()


  private:
     char *str;
     size_t str_length;
     .
     .
     .
};



wie du nun konkret die Spaces löschen willst ist geschmacksfrage. Du brauchst dafür eigentlich kein zwischenarray da du die buchstaben ja auch direkt verschieben kannst... wenn du ganz faul bist lässt du das memmove für dich machen oder du arbeitest mit zwei zeigern. der eine zeigt dahin wo der nächste buchstabe geschrieben wird und der andere an die stelle wie weit du dich schon durch den string gearbeitet hast...
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
011
25.05.2005, 14:04 Uhr
0xdeadbeef
Gott
(Operator)


Mal eben so hingekladdet:

C++:
#include <stdio.h>

char *remove_spaces(char *dest, size_t n, char const *src) {
  char *dest_itr = dest;

  while(dest_itr - dest < n - 1) {
    while(*src == ' ') {
      if(!*src) {
        *dest_itr = 0;
        return dest;
      }
      ++src;
    }
    *dest_itr++ = *src++;
  }
  *dest_itr = 0;

  return dest;
}

char *remove_spaces_nocopy(char *buf) {
  char const *read_p;
  char *write_p= buf;

  while(*write_p != ' ') {
    ++write_p;
  }
  read_p = write_p;

  while(*read_p) {
    while(*read_p == ' ') {
      if(!*read_p) {
    *write_p = 0;
    return buf;
      }
      ++read_p;
    }
    *write_p++ = *read_p++;
  }

  *write_p = 0;
  return buf;
}

int main(void) {
  char buf[100], buf2[] = "  Hello,  World  !  ";

  printf("\"%s\"\n", remove_spaces(buf, 100, "  Hello, World  !"));
  printf("\"%s\"\n", remove_spaces_nocopy(buf2));

  return 0;
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 25.05.2005 um 14:08 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
012
31.05.2005, 15:01 Uhr
Lumina



Also, das ist meine Klasse:

C++:
// Definition der Klasse CString

#ifndef CSTRING_H
#define CSTRING_H

#include <iostream.h>

class CString
  {
public:
   CString();                       // Standardkonstruktor
   CString(const char*);            // Typumwandlungskonstruktor
   CString(const CString&);         // Copy-Konstruktor
   ~CString();                      // Destruktor

   // Operatoren:
   //operator const char* () const { return(str);} // Typkonvertierungs-
                                                 //  operator; verträgt sich nicht
                                                 // mit Indexoperator!

   CString& operator=(const CString&); // Zuweisungen
   CString& operator=(const char*);
                                      
   friend ostream& operator<<(ostream&, const CString&); // Ausgabe

   // Indexoperator
   char& operator[](unsigned);

   int mystrlen(const char*);
   int CStringLen();

   void CStringCat(CString&);    // FEHLERHAFT!!!

   void removeSpaces();
   CString trim();
   char& charAt(unsigned);

private:
   char*    str;                    // Zeiger auf Stringanfang
   unsigned len;                    // enthaelt Stringlaenge
  };

#endif




Hier ein Ausschnitt aus CString.cpp:

C++:
/*******************************************************
* Methode: CStringCat
* Zweck:   Hängt alle Zeichen des CString-Objekts src
*           an das aktuelle  CString-Objekt an.
*******************************************************/

void CString::CStringCat(CString& src) {

   // Anfänge merken:
   char* this_start = str;
   char* src_start = src.str;

   // neue Zeichenkette anlegen:
   char* tmp = new char[mystrlen(str) + mystrlen(src.str) + 1];

   // Anfang der neuen Zeichenkette merken:
   char* tmp_start = tmp;

   // Zeichenketten in neue kopieren:
   for (; *str; str++, tmp++) {
       *tmp = *str;
   }

   while (*tmp++ = *src.str++);

   *tmp = 0; // Nullterminierung setzen

   // Auf Anfänge zurücksetzen:
   str = this_start;
   src.str = src_start;
   tmp = tmp_start;

   delete [] this->str;
   str = tmp;  // Neue Zeichenkette zuweisen
   len = mystrlen(str);
}


Hab schon stundenlang debugged, komm aber einfach nicht drauf, woran es liegt, dass ich bei CStringCat eine Meldung bekomme:

Debug Error!
Program: ... \uebungString.exe
DAMAGE: after Normal block (#60) at 0x003227F8
(Please retry to debug the application)

Der Destruktor kann meine CString-Objekte nur freigeben, wenn der Zeiger auch wirklich am Anfang der Zeichenkette steht, aber das tut er doch, oder nicht?! Es wird ja sogar das richtige ausgegeben in meinem Testprogramm. Aber bei der letzten { im main kommt die obige Meldung... Was ist also falsch?!

removeSpaces funzt und taugt mir so, wie ichs schon mal gepostet hab, danke trotzdem.
--
*******************************************
Willst du glücklich sein im Leben, trage bei zu and'rer Glück,
denn die Freude, die wir geben, kehrt ins eig'ne Herz zurück!
*******************************************
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
013
31.05.2005, 15:30 Uhr
virtual
Sexiest Bit alive
(Operator)


Siehe Anmerkungen im Quelltext.

Zitat von Lumina:
Also, das ist meine Klasse:

C++:
void CString::CStringCat(CString& src) {

   // Anfänge merken:
   char* this_start = str;
   char* src_start = src.str;

   // neue Zeichenkette anlegen:
   char* tmp = new char[mystrlen(str) + mystrlen(src.str) + 1];

   // Anfang der neuen Zeichenkette merken:
   char* tmp_start = tmp;

   // Zeichenketten in neue kopieren:

/* VIRTUAL:
   Muss im folgenden nicht this_start verwendet werden, anstelle von str?
   Du zermatscht dir sonmst this
*/

   for (; *str; str++, tmp++) {
       *tmp = *str;
   }

/*
   VIRTUAL:
   Mit gleicher Begründung wie oben: src_start an stelle von src.str verwenden!
*/

   while (*tmp++ = *src.str++);

/*
   VIRTUAL:
   Hier hast Du das 0 Byte aber schon kopiert! BEachte  
   Schleifenbedingung! - ggf. wird also über Arraygrenze hinausgeschrieben
*/

   *tmp = 0; // Nullterminierung setzen


/*
   VIRTUAL:
   Den kram kannst Du Dir sparen, wenn Du die ersten Beiden Anmerkunen von mir ernst nimmst. Wäre sauberer!
*/

   str = this_start;
   src.str = src_start;
   tmp = tmp_start;

/*
   VIRTUAL:
   tmp Zeigt aber auf das ENDE vom zusammengesetzten String! - Oh weh!
*/

   delete [] this->str;
   str = tmp;  // Neue Zeichenkette zuweisen
   len = mystrlen(str);
}




Alternative:

C++:
void CString::CStringCat(const CString& src) {
  
   char* tmp = new char[len + src.len +1];
   for(int i=0; i<len; ++i) {
      tmp[i] = str[i];
   }
   for(int i=0; i<src.len; ++i) {
     tmp[len+i] = src.str[i];
   }

   len += src.len;
   tmp[len] = 0;
   delete [] str;
   str = tmp;
}


--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 31.05.2005 um 15:32 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
014
31.05.2005, 15:39 Uhr
virtual
Sexiest Bit alive
(Operator)


Oh - ich nehme den letzten Einwand zurück:
tmp Zeigt doch auf den Start des Speichers.

Dennoch:
Deine Routine enthält den Fehler, daß sie ein Byte hinter den belegten Speicher schreibt; das ist das eine Problem.

Außerdem finde ich den Aufbau der Routine ziemlich unkonventionell und würde bei mir durch die QA fallen: Du veränderst zwischenzeitlich src, ohne daß es dafür einen Grund geben würde.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
015
31.05.2005, 17:18 Uhr
(un)wissender
Niveauwart


Elegant ist auch sowas:


C++:
#include <functional>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cctype>

int main()
{
    const char * const inputWithSpaces = " Hallo, du! ";
    const int length = std::strlen(inputWithSpaces) + 1;
    char * inputWithoutSpaces = new char[length];
    std::remove_copy_if(inputWithSpaces, inputWithSpaces + length, inputWithoutSpaces, std::ptr_fun(isspace));
    std::cout << inputWithSpaces << '\n';
    std::cout << inputWithoutSpaces << '\n';
    delete [] inputWithoutSpaces;
}


--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
016
31.05.2005, 17:49 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)



Zitat:

Elegant ist auch sowas:




C++:
const char * const...


ich kann da nix elegantes dran finden sich selbst zu beschränken *SCNR*
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
017
31.05.2005, 17:51 Uhr
0xdeadbeef
Gott
(Operator)


Heißt das, die Member deiner Klassen sind alle public?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
018
01.06.2005, 09:52 Uhr
(un)wissender
Niveauwart


@Windalf
Ach Windalf, ich glaube, ich schicke demnächst mal die Russen meines Vertrauens zu dir...
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
019
01.06.2005, 10:06 Uhr
Lumina



@ virtual:
Du hattest Recht! Es ist wegen der Nullterminierung... es wurde zwar das Richtige ausgegeben in meinem Hauptprogramm, aber es stand die zweite Nullterminierung wohl in nem Speicher, der nicht zu meinem Array gehörte, also Fehler. Darum ist mir die for-Schleife lieber... while-Schleifen mag ich net so...
DANKE!

Und das mit dem anderen Zeiger durchlaufen lassen, ist auch eine gute Anmerkung, aber nicht zwingend notwendig für das funktionieren meiner Funktion.

@Oxdeadbeef:
Die Member meiner Klasse sind natürlich private.... Datenkapselung ist ein Muss. Oder meintest du (un)wissenden?!
--
*******************************************
Willst du glücklich sein im Leben, trage bei zu and'rer Glück,
denn die Freude, die wir geben, kehrt ins eig'ne Herz zurück!
*******************************************
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: [ 1 ] > 2 < [ 3 ] [ 4 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: