Fehler bei string.erase()

Neogen1

Grünschnabel
Hallo

Folgendes Problem in C++:
Eine Datei wird in einen string kopiert, und danach mir .erase() einzelne elemte gelöscht.

Hier erstmal der teil der funktion

PHP:
//Länge des streams ermitteln
            size_t size;
            finput.seekg(0, ios::end);
            size = finput.tellg();
            finput.seekg(0, ios::beg);
            
            //Buffer auf stream größe erweitern
            
            buffer.resize(size+1, '~');
            
            //Datei in Buffer kopieren
            int index=0;
            
            while(finput.get(ch)){
               buffer.at(index)=ch;
               index++;
               }
            
            //Das Wort " Angreifen" aus dem Buffer löschen
            
            int pos;
            while(pos != 0){
               pos = buffer.find(angreifen, 0);
               if(pos!=0)buffer.erase(pos, 10);
               cout<<pos<<"  ";
               Sleep(10);
            }

Die letzten 2 Zeilen, cout und sleep sind nur zum debuggen.
Wenn das Programm nun bei der while-Schleife ankommt, löscht er ungefähr 100 Objekte und gibt mir dann den Fehler aus bei position 6064 im string.

This application has requested the Runtime to terminate it in an unsual way.

Wenn ich das File Kürze, kommt der Fehler früher.

Hab die Datei mit dem Hex-Editor untersucht und den Wert der Positionen überprüft, es sind jedoch immer unterschiedliche Werte.

Google spuckt auch nichts brauchbares aus.

Wenn ich die while schleife weglasse, und nur einmal .erase() verwende funktioniert es.
 
Zuletzt bearbeitet:
Hi.

Deine if-Bedingung ist falsch. Die Methode find von std::string liefert string::npos zurück falls der String nicht gefunden wurde. Außerdem hast du pos vor der Schleife nicht initialisiert.

Gruß
 
C++:
finput.seekg(0, std::ios_base::end);
const std::size_t size(finput.tellg());
finput.seekg(0, std::ios_base::beg);
            
// Buffer auf stream größe erweitern
buffer.resize(size+1, '~');
            
// Datei in Buffer kopieren
std::size_t index(0);

while (finput.get(ch))
{
    buffer.at(index)=ch;
    index++;
}
... Also, soll ich mal kommentieren wo du Performance verlierst, was du anderes lösen kannst, solltest?
C++:
finput.seekg(0, std::ios_base::end); 
const std::size_t size(finput.tellg());
finput.seekg(0, std::ios_base::beg);
            
// Buffer auf stream größe erweitern
buffer.resize(size+1, '~'); // warum legst du nicht hier erst den Buffer an? Und warum + 1? darum musst du dich nicht kümmern ... das war unter C so, std::string macht das selber!
            
// Datei in Buffer kopieren
std::size_t index(0); // mach eine for-Schleife daraus ... dann ist index auch nach dem ablauf hinüber ;)

while (finput.get(ch)) // so kann man notfalls auch einlesen, einfacher: while (finput >> buffer[index++]);
{
    buffer.at(index)=ch; // at verschenkt Performance, da du jedesmal nen range-check machst. Einfach Indexoperator, oder noch besser: Iteratoren nehmen.
    index++; // in fall von integer egal, sonst ist ++x dem x++ vorzuziehen
}
=>
C++:
finput.seekg(0, std::ios_base::end);
const std::size_t size(finput.tellg());
finput.seekg(0, std::ios_base::beg);
            
// Buffergröße auf 'size' setzen
buffer.resize(size);
            
// Datei in Buffer kopieren
for (std::size_t index(0); finput; ++index) finput >> buffer[index];
Das wäre schonmal besser. Jetzt kommt Ultralösung nr. 1:
C++:
const std::string buffer(std::istream_iterator<char>(finput), std::istream_iterator<char>());
Und auch ne Möglichkeit:
C++:
std::ostringstream ss;
ss << finput.rdbuf();
buffer = ss.str();
;)


Dann weiter zu deinem Suchen:
C++:
int pos; // undefinierter Wert, -Wertebereich. Was du brauchste: std::size_t
            while(pos != 0)
            {
               pos = buffer.find(angreifen, 0); // immer ganz vorne im String anfangen? Performance 0% ;)
               if (pos!=0) buffer.erase(pos, 10); // das ist doppelt gemoppelt. (vgl. while)
               cout<<pos<<"  ";
               Sleep(10); // warum sleep? soll es lahm werden? ^^
            }
=>
C++:
for (std::size_t pos(buffer.find(angreifen, 0)); pos != std::string::npos; pos = buffer.find(angreifen, pos + 1)) buffer.erase(pos, angreifen.length());
... das geht schon besser :)
 
Ehm ja XD
Wieso ich des ned so mache hat einen einfachen Grund:

Ich kenn mich noch ned so gut aus ^^

Bin noch am durcharbeiten von meinem Buch und versuche eben, das ganze so zu lösen dass ich daraus was lernen kann.

aber hab den code jetz selbst schon etwas optimiert.

C++:
while(finput.get(ch)){    //In String kopieren
   buffer+=ch;
}

int pos=1;
do{
      pos = buffer.find(" Angreifen", pos+1);
      if(pos!=string::npos)buffer.erase(pos, 10);
}while(pos != string::npos);

Is zwar wahrscheinlich noch immer ned optimal aber fürn anfang reichts.

Wo ich grad dabei bin.
Versuch grad den buffer in eine datei zu kopieren, also nach dem entfernen verschiedenster sachen, nur irgendwie stürzt entwerder immer das Programm ab oder ich bekomm wieder diesen Error. File->File wär ja kein problem, aber String->File, da fin dich nix passendes.

Kennt da wer ne Lösung? Googel schon seit 2 Stunden -.-

#EDIT

Vielen dank für die Infos zu den schwachstellen ^^. Hab jetz paar sachen umgebaut.

Zum "// warum legst du nicht hier erst den Buffer an?" , die funktion liegt in einer if-Anweisung, da die daten je nach Quelle anders bearbeitet werden müssen. Atm gibt es nur die eine möglichkeit, die anderen baue ich erst ein wenn diese hier mal einwandfrei läuft ^^.
 
Zuletzt bearbeitet:
Zurück